简单介绍
父组件 向 子组件 传递值
步骤:
- 在父组件中引入子组件
- 注册子组件
- 在页面中使用,子组件标签上 动态绑定传入动态值 / 静态值
- 在子组件中,使用 props 来接受 父组件 传递过了的值
子组件接收的父组件的值分为引用类型和普通类型两种:
- 普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
- 引用类型:数组(Array)、对象(Object)
father.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <template> <div> <Test :obj="obj" info="测试"/> </div> </template>
<script>
import Test from './children.vue'; export default { name: "about", components: { Test, }, data() { return { obj: { code: 200, title: "一起自学Vue吧!", }, }; }, }; </script>
|
children.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <h1>{{obj.code}}</h1><br> <h2>{{obj.title}}</h2> <h3>{{info}}</h3> </div> </template>
<script> export default { name:'test', props:{ obj:Object, info: [String,Number] } } </script>
|
由于 Vue 是 单向数据流, 子组件 是不能直接 修改 父组件 的 值。
子组件 向 父组件 传递值
子组件通过绑定事件,通过 this.$emit(‘函数名’,传递参数)
father.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <Test :obj="obj" info="测试" @modify="modifyFatherValue"> </template>
<script>
import Test from "./children.vue"; export default { name: "about", components: { Test, }, data() { return { msg:'我是父组件' }; }, methods:{ modifyFatherValue(e){ console.log(e) } } }; </script>
|
children.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <h1>{{obj.code}}</h1><br> <h2>{{obj.title}}</h2> <h3>{{info}}</h3> </div> </template>
<script> export default { name:'test', props:{ obj:Object, info: [String,Number] } } </script>
|
父组件 通过 $refs / $children 来获取子组件值
$refs :
- 获取DOM 元素 和 组件实例来获取组件的属性和方法。
- 通过在 子组件 上绑定 ref ,使用 this.$refs.refName.子组件属性 / 子组件方法
$children :
- 当前实例的子组件,它返回的是一个子组件的集合。如果想获取哪个组件属性和方法,可以通过 this.$children[index].子组件属性/f方法
text1.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <script> export default { name:'test', data() { return { datas:"我是子组件值" } }, props:{ obj:Object, info: [String,Number] }, methods:{ getValue(){ console.log('我是Test1') } } } </script>
|
text2.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div> <h1>我是Test2</h1> </div> </template>
<script> export default { name:'test', data() { return { datas:"我是Test2" } }, created(){ console.log( this.$parent.obj ) this.$parent.getQuery() }, methods:{ getTest2(){ console.log(this.datas) } } } </script>
|
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> // 给子组件上绑定 ref <Test1 ref="son" /> <Test2/> </div> </template>
<script>
console.log( this.$refs.son.datas) this.$refs.son.getValue()
this.$children[0].getValue(); this.$children[1].getTest2(); console.log(`${this.$children[1].datas}`); </script>
|
子组件 通过 $parent 来获取父组件实例的属性和方法
children.vue1 2 3 4 5 6 7 8 9
| <script> export default { name:'test', created(){ console.log( this.$parent.obj ) this.$parent.getQuery() }, } </script>
|
$attrs 和 $listeners 获取父组件实例属性和方法(组件嵌套情况下使用)
$attrs:包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind=” $attrs” 传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。
$listeners:包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。
使用场景: 多层嵌套组件的情况下使用,可以避免使用Vuex来做数据处理, 使用 v-bind=”$attrs” v-on=”$listeners” 很方便达到业务数据传递。
father.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <template> <div> <Test1 :status="status" :title="title" @getData="getData" /> </div> </template>
<script> import Children1 from "./children1.vue"; export default { name:'person', data(){ return { title:'personal 组件', status: false } }, methods:{ getData(){ console.log(this.title) } }, components:{ Children1 } } </script>
|
children1.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div> <h1>children1 组件</h1> <br /><br /> // 通过 $attrs(属性,除了【props中定义的属性】) 和 $listeners(方法) 来给嵌套子组件传递父组件的属性和方法 <Children2 v-bind="$attrs" v-on="$listeners"/> </div> </template>
<script>
import Children2 from "./children2.vue"; export default { name: "Children1", props: ["title"], components: { Children2, }, created() { console.log(this.$attrs); console.log(this.$listeners); }, }; </script>
|
children2.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <h1>children2 组件</h1> </div> </template>
<script> export default { name:'Children2', created(){ console.log('-----children2------') console.log(this.$attrs) console.log(this.$listeners) } } </script>
|
跨组件之间传值(eventBus)
通过新建一个 js
文件,导入 vue
, 导出 vue
实例; 然后通过 给导出的实例 上绑定事件 $emit
事件 , 然后再通过 $on
监听触发的事件,这样就可以达到全局组件数据共享。
使用场景:它可以满足任意场景传递数据, 父子组件传值 , 子父传值 , 兄弟组件之间传值 , 跨级组件之间传值。
通信数据比较简单时,可以采用这种方案,eventBus也有不方便之处, 当项目较大,就容易造成难以维护的灾难,这时候可以采用 Vuex
。
myVue.js1 2 3
| import Vue from 'vue'
export default new Vue()
|
组件A1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div> <button @click="changeValue">改变</button> </div> </template>
<script> import myVue from './myVue.js' export default { name:'person', data(){ return { title:'personal 组件', status: false } }, methods:{ changeValue(){ myVue.$emit('getTitle', this.title) } } } </script>
|
组件B1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div> <h1>Test4 组件</h1> <h1>{{ title }}</h1> </div> </template>
<script> import myVue from "./myVue.js" export default { name: "test4", data() { return { title: "test4", } }, mounted(){ myVue.$on('getTitle', (item) => { this.title = item }) } }; </script>
|
provide 和 inject 实现父组件向子孙孙组件传值。(层级不限)
provide 和 inject 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
provide:是一个对象或返回一个对象的函数,该对象包含可注入其子孙的属性。
inject:是一个字符串数组 或者是一个对象,用来在子组件或者子孙组件中注入 provide 提供的父组件属性。
使用场景:provide/inject可以轻松实现跨级访问父组件的数据
father.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <h1>我是父组件</h1> <Son /> </div> </template>
<script> import Son from './SonOne' export default { provide(){ return { title: '父组件的值' } }, components:{ Son } } </script>
|
SonOne.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div> <h1>我是子组件</h1> <SonTwo /> </div> </template>
<script> import SonTwo from './SonTwo' export default { components:{ SonTwo }, inject:['title'], created(){ console.log(this.title) } } </script>
|
SonTwo.vue1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <h1>我是子孙组件</h1> </div> </template>
<script> export default { components:{ SonTwo }, inject:['title'], created(){ console.log(this.title) } } </script>
|
Vuex、localStorage / sessionStorage
Vuex请看:Vue学习笔记(4):Vuex基础
localStorage请看:Html5学习笔记,这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护。