目录
前言
父子组件
父传子
子传父
全局事件总线
什么叫全局事件总线
如何创建全局事件总线
如何在组件上获取到这个全局vc对象
最常用的创建全局事件总线
兄弟组件
消息订阅与发布
安装
使用
爷孙组件
前言
在上篇文章我们介绍了父子组件之间的传值通信,本文将介绍不仅限于父子组件之间的传值通信,还包括兄弟组件、爷孙组件之间的通信传值。以下方法暂未涉及到Vue3中新提供的方法
父子组件
父传子
在父组件中
给需要传递数值的子组件绑定属性
<template><div id="app"><MySon name="zs" age=20 gender="男"></MySon></div> </template><script> import MySon from './components/MySon.vue'export default {name: 'App',components: {MySon} } </script>
在子组件中
使用props配置项接收
<template><div>姓名:{{ name }}年龄:{{ age }}性别:{{ gender }}</div> </template><script> export default {name:'MySon',props:['name','age','gender'] } </script>
传递成功,在页面上成功渲染
以上介绍的是基本的而props配置项,props详情配置项请看这篇文章
子传父
在父组件中
@自定义事件名='回调函数'
<template><div id="app"><MySon @event1="think"></MySon></div> </template><script> import MySon from './components/MySon.vue'export default {name: 'App',components: {MySon},methods:{think(name,age,gender){console.log(name,age,gender);}} } </script>
也可以通过代码来实现自定义事件绑定
在子组件用
ref='组件名'
在mounted钩子函数中
this.$refs.ref定义的组件名.$on('自定义的事件名',函数)
<template><div id="app"><MySon ref="MySon"></MySon></div> </template><script> import MySon from './components/MySon.vue'export default {name: 'App',components: {MySon},methods:{think(name,age,gender){console.log(name,age,gender);}},mounted(){this.$refs.MySon.$on('event1',this.think)} } </script>
在子组件中
this.$emit('自定义事件名',传递的数值)
将子组件中数值传给父组件
传递成功
全局事件总线
什么叫全局事件总线
在介绍兄弟组件和爷孙组件前,先介绍全局事件总线
由上面的子组件向父组件传递数值可以得出
$on:是用来绑定事件的
$emit:是用来触发事件的
例:
子组件向父组件传递数值
所以子组件使用的是$emit
父组件使用的是$on
而全局事件总线就是在所有的组件外面定义一个全局的vc对象,由上面的例子可得
不论是在父组件中用来绑定事件的$on前的
this.$refs.组件实例
还是在子组件中用来触发事件的$emit前的
this
都是指向vc组件实例的,说明vc实例身上是同时拥有$on和$emit的
此时我们定义一个全局的vc对象,所有的组件都可以共享
那么我们定义的这个全局的vc对象就叫做全局事件总线
如何创建全局事件总线
既然是创建全局事件对象,所以我们找到main.js文件
使用
vue.extend({})
创建构造函数
再 new 一个vc实例对象
// 获取VueComponent构造函数 const VueComponent = Vue.extend({}) // 创建共享的vc对象 const globalvc = new VueComponent()
如何在组件上获取到这个全局vc对象
利用vue的原型对象,vue做了特殊处理,vc也可以获取到vue原型对象身上的属性
vue.prototype.任意的属性名=我们创建的vc对象
// 拓展原型对象的属性 Vue.prototype.x=globalvc
// 获取VueComponent构造函数
const VueComponent = Vue.extend({})
// 创建共享的vc对象
const globalvc = new VueComponent()
// 拓展原型对象的属性
Vue.prototype.x=globalvc
最常用的创建全局事件总线
new Vue({render: h => h(App),beforeCreate(){Vue.prototype.$bus=this}
}).$mount('#app')
兄弟组件
由上可知全局事件总线可以给任意的组件之间进行通信
将MyBrother组件上的数据传给兄弟组件MySon
在MySon组件中
<template><div><button @click="think2()">传递</button></div> </template> <script> export default {name:'MySon',data(){return {name:'haha',age:18,gender:'女'}},mounted(){this.x.$on('event2',this.think3)},methods:{think2(){this.$emit('event1',this.name,this.age,this.gender)},think3(name,age,gender){this.name=namethis.age=agethis.gender=gender}} } </script>
在MyBrother组件中
将data中的数值传给MySon
<template><div><button @click="emit">发送</button></div> </template><script> export default {name:'MyBrother',data(){return {name:'兄弟',age:20,gender:'男'}},methods:{emit(){this.x.$emit('event2',this.name,this.age,this.gender)}} } </script>
原MySon中的data数据
当触发自定义事件时,也就是将MyBrother组件中的数值传过去
成功传递
消息订阅与发布
与全局事件总线一样可以在任何组件之间通信(但是不常用,建议用全局事件总线)
分为消息发布方和消息订阅方
需要安装js第三方库
pubsub-js
pub:publish(发布)
sub:subscribe(订阅)
安装
npm i pubsub-js
使用
发布消息:
pubsub.publish('自定义发布消息的名称',发布的消息)
订阅消息:
后接回调函数,第一个参数是自定义发布消息的名称,第二个参数是发布的消息
pubsub.subscribe('与发布消息自定义的名称一致',function(messageName,message){})
注意,在组件中使用时,需要先导入import
爷孙组件
在孙组件中
发布消息,将数据传给爷爷组件
<template><div><button @click="think">发布消息</button></div> </template><script> import pubsub from 'pubsub-js' export default {name:'GrandSon',data(){return {msg:'消息发布成功'}},methods:{think(){pubsub.publish('发布消息',this.msg)}} } </script>
在爷爷组件中
在mounted钩子函数中
<template><div id="app"><GrandSon></GrandSon></div> </template><script> import pubsub from 'pubsub-js' import GrandSon from './components/GrandSon.vue'; export default {name: 'App',components: {GrandSon},mounted(){pubsub.subscribe('发布消息',function(messageName,message){console.log(messageName,message);})} } </script>
效果
成功传递了数据