Vue组件通信__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
父子组件通信
props 和 $emit
props和$emit这是我们日常开发中最常使用的组件通信方式。父组件通过绑定属性来向子组件传递数据,子组件通过 props 属性来获取对应的数据,子组件则是通过派发 $emit事件将数据传递到父组件中。
//父组件parent.vue
<child :msg="msg"
@updateParentMsg="updateParentMsg" />
data() {
return {
msg: 'parent msg',
}
},
methods: {
updateParentMsg(msg) {
this.msg = msg
}
}
//子组件child.vue
//接收父组件传递的数据
props: {
msg: String
},
methods: {
change() {
//派发一个updateParentMsg事件
this.$emit('updateParentMsg', 'child msg')
}
}
$children / $parent / ref
- ⽗组件可以通过$children访问⼦组件,子组件可以通过 $parent来访问父组件,不过一般情况下不推荐通过这种方式来实现组件通信。
- ref: 访问子组件实例或子元素,使用后可以直接访问子组件的数据或调用子组件的方法。
非父子组件通信
事件总线
任意两个组件之间传值常⽤事件总线 或 vuex的⽅式。
// Bus:事件派发、监听和回调管理
class Bus {
constructor(){
this.callbacks = {}
}
$on(name, fn){
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name, args){
if(this.callbacks[name]){
this.callbacks[name].forEach(cb => cb(args))
}
}
}
// main.js
Vue.prototype.$bus = new Bus()
// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')
实践中通常⽤Vue代替Bus,因为Vue已经实现了相应接⼝
//main.js
Vue.prototype.$bus = new Vue()
Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式,通过它集中式的管理数据并通知组件状态变更。推荐在项目复杂的情况下使用。
provide/inject
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。用于祖先组件和后代组件之间的通信,无论组件的层次有多深
//祖先组件
provide() {
return {foo: 'foo'}
}
//后代组件
inject: ['foo']
注意:provide 和 inject 并非响应式的。当我们传入对象时,其对象中的属性便是响应式的。
$attrs / $listeners
包含了⽗作⽤域中不作为 prop 被识别(且获取)的特性绑定(class和style除外)。当⼀个组件没有 声明任何 prop 时,这⾥会包含所有⽗作⽤域的绑定(class 和 style 除外),并且可以通过 v-bind=" $attrs"传⼊内部组件—在创建⾼级别的组件时⾮常有⽤。
//parent.vue
<child :msg="msg"
foo="foo"
@updateParentMsg="updateParentMsg" />
//child.vue 并未在props中声明foo
<GrandSon v-bind="$attrs"
v-on="$listeners" />
//GrandSon.vue
<p [@click](/user/click)="change">{{$attrs.foo}}</p>
methods: {
change() {
this.$emit('updateParentMsg', 'GrandSon msg')
}
}
```<p style="line-height: 20px; color: #ccc">
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者: Yangi
原文链接:<a href='https://juejin.im/post/6856359634039963656'>https://juejin.im/post/6856359634039963656</a>
</p>