一、组件间通信的概念
指组件( .vue )通过某种方式来传递信息以达到某个目的。举个例子:我们在使用 UI 框架中的 table 组件,可能会往 table 组件中传入某些数据,这个本质就形成了组件之间的通信。
二、组件通信的作用
在vue中,每个组件之间都有独自的作用域,组件间的数据是无法共享的。但实际开发工作中我们常常需要让组件之间共享数据,这也是组件通信的目的要让它们互相之间能进行通讯,这样才能构成一个有机的完整系统。
三、Vue 组件如何进行传值的
1. 父子组件通信
1.1 父组件向子组件传递数据
- 父组件通过
自定义属性名="需要传递的数据"
,子组件通过props
接收
// Father.vue 组件
<Children name:"yang" age=18 />
// Children.vue 组件
props:{
name:String
age:{
type:Number,
defaule:18,
require:true
}
}
- 父组件通过
v-model
传递需要的参数,子组件props
中通过value
接收(适用于基本数据类型) - 父组件通过
自定义属性名.sync="需要传递的数据"
,子组件通过props
接收(适用于基本数据类型)
1.2 子组件向父组件传递数据
- 子组件通过
$emit('自定义事件名', 传递的参数)
,父组件@自定义事件名="绑定的自定义方法($event)"
// Father.vue 组件
<Children @add="numAdd($event)" />
// Children.vue 组件
this.$emit('add', 12)
- 子组件可直接通过
$emit('input', 需要改变的值)
(适用于基本数据类型) - 子组件可直接通过
$emit('update:自定义属性名', 需要改变的值)
(适用于基本数据类型)
1.3 其他方法
ref/$refs
: 父组件通过$refs
可直接调用子组件的数据和方法 可读不可改
// Father.vue 组件
<Children ref="foo" />
this.$refs.foo
$parent / $children
: 使用$parent
访问父组件实例,$children
访问子组件实例 注意: $children拿到的是所有组件的实例,是一个数组,且是无序的
1.4 适用于父子传参 及 祖先后代传参
- 依赖注入 -
provide/inject
: 父组件使用provide
来传参,所有子组件都可以获取到,需要参数的子组件通过inject
来接收(可读不可改)
// 祖先组件
provide(){
return {
foo:'foo'
}
}
// 后代组件
inject:['foo']
$attrs 和 $listeners
(可以批量传数据或方法)$attrs
不包括props
传递的属性,$listeners
包括了所有作用在这个组件上的监听器
// Father.vue 组件
<Child name="yang" @test="test"></Child>
// Child.vue 组件
<Grandson v-bind="$attrs" v-on="$listeners"></Grandson>
// 在祖先组件中使用
props:['name']
created(){
this.$emit('test')
console.log(this.$attrs)
}
2. 兄弟组件通信
eventBus事件总线: 创建一个中央事件总线 EventBus
,兄弟组件通过 $emit
触发自定义事件,$emit
第二个参数为传递的数值,另一个兄弟组件通过 $on
监听自定义事件
3. 无直接关系组件通信
Vuex
vuex相当于一个存储共享变量的容器
- state:存放共享变量
- mutations:存放修改state的方法
- actions:存放异步方法,在mutations的基础上进行
- getters:相当于计算属性,用来获得共享变量的值
- modules:将项目中的各个模块分开定义和操作
四、小结
- 父子关系的组件数据传递选择 props 与 $emit 进行传递,也可选择 ref
- 兄弟关系的组件数据传递可选择
$bus
,其次可以选择 $parent 进行传递 - 祖先与后代组件数据传递可选择 attrs 与 listeners 或者 Provide 与 Inject
- 复杂关系的组件数据传递可以通过 vuex 存放共享的变量