组件-组件通信的几种情况
组件嵌套 => 父子组件 => 父组件传递数据给子组件使用 => 组件之间的传值 => 也叫组件之间的通信
组件之间的通信根据关系的可以分为:
- 父子组件通信
- 父组件到子组件
- 子组件到父组件
- 兄弟组件通信
父子组件传值-props属性
父子组件的传值有多种方法, 兄弟组件的通信也有自己的写法
子组件的 props 属性值是一个数组
数组中的值 绑定为子组件上的属性 用来接受父组件的传值
在子组件的template中就可以使用 绑定的属性(msg)拿到父组件传递的值
// 调用组件 <div id="app"> <child-a :msg="msgParent"></child-a> </div> // 子组件 Vue.component("child-a", { template: ` <div> 我是子组件 {{count}}是自己的data中的数据count {{msg}}是来源于外部组件的数据</div> </div>`, data() { return { count: 100 } }, props: ["msg"] }) // 父组件(根组件) new Vue({ el:'#app' data: { msgParent: "我是父组件" } })
父子组件传值-组件的自定义事件
-
一种组件间的通信方式,适用于: 子组件传递给父组件
-
使用场景: A是父组件,B是子组件,B给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中).
-
绑定自定义事件:
-
第一种方式,在父组件中:
<Demo @chuan = "test" />
或<Demo v-on:chuan="test" />
-
第二种方式,在父组件中:
<Demo ref= "demo" /> .............. mounted(){ this.$refs.xxx.$on('chuan',this.test) //this.$refs.xxx.$once('chuan',this.test) } //若想让自定义事件只触发一次,可以使用once修饰符或者 $once方法
-
-
触发自定义事件:
this.$emit('chuan',数据)
-
解绑自定义事件:
this.$off('chuan')
或this.$off()
清空所有 -
组件上也可以绑定原生DOM事件,需要使用native修饰符
-
注意:通过
this.$refs.xxx.$on('chuan',回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!!!
全局事件总线
- 一组组件间通信的方式,适用于任意组件间通信
- 安装全局事件总线:在main.js中
new Vue({
el: '#app',
render: (h) => h(App),
//安装全局事件总线
beforeCreate() {
//$bus就是当前应用的vm
Vue.prototype.$bus = this;
},
});
- 使用事件总线:
- 接收数据:A组件想要接收数据,则在A组件中给$bus绑定自定义事件,事件的回调函数留在A组件自身
- 提供数据:
this.$bus.$emit('绑定名',数据)
methods(){
demo(data){...........}
}
mounted() {
this.$bus.$on('绑定名', this.demo)
})
},
- 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件,谁用谁解绑.
beforeDestroy() {
//销毁组件前要记得解绑自定义事件
this.$bus.$off('hello')
},
消息订阅与发布(pubsub-js)
- 一种组件间通信的方式,适用于任意组件间通信.
- 使用步骤:
- 安装pubsub:
npm i pubsub-js
- 在需要的组件引入:
import pubsub from 'pubsub-js'
- 接收数据:A组件想要接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
- 提供数据:
pubsub.publish('xxx',数据)
- 最好在beforeDestroy钩子中,用
pubsub.unsubscribe(pid)
去取消订阅
- 安装pubsub:
methods(){
demo(data){..........}
}
mounted(){
this.pid = pubsub.subscribe('xxx',this.demo)//订阅消息
}
beforeDestroy(){
pubsub.unsubscribe(this.pid)
}