从vue1.x过来的都知道,在vue2.0中,父子组件间事件通信的$dispatch和$broadcase被移除了。官方考虑是基于组件树结构的事件流方式实在是让人难以理解,并且在组件结构扩展的过程中会变得越来越脆落。特别是在组件层级比较深的情况下。通过广播和事件分发的机制,就显得比较混乱了。
官方在废除的同时,也为我们提供了替换方案,包括实例化一个空的vue实例,使用$emit反应子组件上的状态变化
1.使用$emit触发事件
helloWorld.vue作为父组件,dialogConfigVisible变量控制子组件弹框显示或隐藏。
configBox.vue作为子组件,假设为封装的公告弹窗。
在父组件中 helloWorld.vue 中
< template/>
<config-box :visible="dialogConfigVisible" @listenToConfig="changeConfigVisible" > </config-box>
script
data(){
return {
dialogConfigVisible:true
}
}
methods: {
changeConfigVisible(flag) {
this.dialogConfigVisible = flag;
}
}
然后,在子组件 configBox.vue 中,主要在任意事件回调中,使用 $emit来触发自定义的 listenToConfig事件,后面还可以加上参数传给父组件。比如,在子组件弹窗上点击×关闭时,通知父组件 helloWorld.vue我要关闭了,主要方便父组件改变相应状态变量,并传入false到自定义的事件中。
script
methods:{
dialogClose() {
this.show = false;
this.$emit("listenToConfig", false)
}
}
在子組件中,主动触发listenToConfig事件,并传入参数 false, 告诉父组件 helloWorld.vue对话框要关闭了。这里就可以避免父组件中的状态未变化,再次刷新页面的时候对话框会自动出现。
2.实例化一个空的vue实例bus
这里实例化一个bus 空vue实例,主要为了统一管理子组件和父组件相互通信,通过bus 作为媒介,首先新建一个bus.js 文件,在里面新建一个对象,父组件为table.vue, 子组件为tableColumn.vue
// bus.js
import Vue from "vue";
export var bus = new Vue({
data:{
scrollY:false
},
methods:{
updateScrollY(flag){
this.scrollY = flag;
}
}
})
然后分别引入:
// table.vue
<script>
import {bus} from "./bus"
export default {
created(){
bus.$on('getData',(argsData)=>{
// 这里获取子组件传来的参数
console.log(argsData);
})
}
}
</script>
// tableColumn.vue
<script>
import {bus} from "./bus"
export default{
methods(){
handleClick(){
bus.$emit('getData',{data:"from tableColumn!"})
}
}
}
</script>
内容版权声明:除非注明,否则皆为本站原创文章。
