之前博客中介绍了prop和调用事件的方式在父-子组件之间进行数据,这种方式在只有一层嵌套层时可以使用,但是路过存在多层嵌套,多层多个"兄弟"组件之间传递数据,就非常麻烦。对此,vue中提供了一种全局事件总线机制,数据传递是通过一个空的Vue实例作为中央事件总线,通过它来触发事件和监听事件,可以实现几乎任何组件间的通信,这在一些比较小的项目中是非常好用的。
全局事件总线相当于一个公共空间,任何组件都可以将事件绑定到其中,任何其他组件都可以去出发绑定到这个公共空间的方法,实现组件之间的数据交互。
使用全局事件总线之前,需要在main.js中进行安装:
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
el:'#app',
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线
},
})
组件将事件绑定到全局事件总线中:
<template>
<div class="demo2">
<hello1
v-for="per in persons"
:key="per.id"
:perObj=per
>
</hello1>
</div>
</template>
<script>
import hello1 from './hello1.vue'
export default {
name: 'hello2',
data(){
return {
persons: [
{ id: 1, name: '张三', age: 23 },
{ id: 2, name: '李四', age: 34 },
{ id: 3, name: '王五', age: 45 }
]
}
},
components:{
hello1
},
mounted() {
this.$bus.$on('changeAge1', (id)=>{ // 将事件changeAge1添加到事件总线中
this.persons.forEach((per)=>{
if(per.id === id) per.age += 1
});
console.log('id值为:', id, 'age值加1')
})
}
}
</script>
其他组件触发事件总线中的事件,实现数据交互:
<template>
<div class="demo1">
<h4>{{perObj.name}} 的年龄是:{{perObj.age}}</h4>
<!-- 此处调用从父组件中传过来的函数 -->
<button @click="changeAge2(perObj.id)">修改年龄</button>
</div>
</template>
<script>
export default {
name: 'hello1',
props:['perObj'],
methods: {
changeAge2(id){
this.$bus.$emit('changeAge1', id)
}
},
}
</script>