从vue1.x过来的都知道,在vue2.0中去掉了父子组件间事件通信的$dispatch和$broadcase。官方的考虑是,基于组件树结构的事件流方式确实很难理解,而且会随着组件结构的扩大而变得越来越脆弱。特别是当组件层次结构很深时。广播和事件分发的机制比较混乱。官方废除了它的同时,也为我们提供了一个替代方案,包括实例化一个空的vue实例,并使用$emit来反映子组件上的状态变化1.使用$emit作为父组件触发事件helloWorld.vue,而dialogConfigVisible变量控制显示或隐藏子组件弹出窗口。configBox.vue作为一个子组件,假设是一个封装好的公告弹窗。在父组件helloWorld.vuescriptdata(){return{dialogConfigVisible:true}}methods:{changeConfigVisible(标志){this.dialogConfigVisible=flag;然后在子组件configBox.vue中,主要是在任意事件回调中,使用$emit触发自定义的listenToConfig事件,然后就可以给父组件添加参数了。比如在子组件的弹窗上点击×关闭时,会通知父组件helloWorld.vue我要关闭了。这主要是为了方便父组件更改相应的状态变量,将false传给自定义事件。脚本方法:{dialogClose(){this.show=false;this.$emit("listenToConfig",false)}}在子组件中,主动触发listenToConfig事件,传入参数false,告诉父组件helloWorld.vuedialog该关闭了。这里可以避免父组件中的状态没有改变,再次刷新页面时会自动出现对话框。2、实例化一个空的vue实例bus这里实例化一个bus的空vue实例,主要是为了统一管理子组件和父组件之间的通信,以bus为媒介,首先新建一个bus.js文件,新建一个其中的对象。父组件是table.vue,子组件是tableColumn.vue//bus.jsimportVuefrom"vue";exportvarbus=newVue({data:{scrollY:false},methods:{updateScrollY(flag){this.scrollY=flag;}}})并分别导入://table.vue//tableColumn.vue在上面的父子组件中,父组件使用总线注册监听事件getData,子组件一旦有状态变化,就会触发总线上对应的事件。这种使用空实例的方式相当于创建了一个事件中心,所以这种通信同样适用于非父子组件之间的通信。3.多级父子组件通信有时候,可能要通信的两个组件不是直接的父子组件,而是祖父孙子,或者跨越更多层级的父子组件,是不可能向上传递参数的从子组件逐层达到通信的目的,虽然我们现在理解的通信是通过中转这种方式的。可以使用while等循环向上遍历,直到找到目标父组件,然后在对应的组件上触发事件。下面是element-ui实现的一个父子组件通信的mixins,对组件同步有很大的作用。在element-ui的优势概述中,这个组件通信函数broadcast(componentName,eventName,params){//向下遍历每个子节点,触发对应的向下广播事件this.$children.forEach(child=>{varname=child.$options.componentName;if(name===componentName){child.$emit.apply(child,[eventName].concat(params));}else{broadcast.apply(child,[componentName,eventName).concat([params]));}});}exportdefault{methods:{//向上遍历父节点得到指定的父节点,通过$emit(componentName)在对应的组件中触发eventName事件派发,eventName,params){varparent=this.$parent||这个.$root;varname=parent.$options.componentName;//上面的componentName需要在每个vue实例中额外配置自定义属性componentName,//可以简单的替换为varname=parent.$options._componentTag;while(parent&&(!name||name!==componentName)){parent=parent.$parent;如果(父母){名字=父母。$options.componentName;}}if(parent){parent.$emit.apply(parent,[事件名称].concat(参数));}},broadcast(componentName,eventName,params){broadcast.call(this,componentName,eventName,params);}}};首先定义两个嵌套组件f1.vue和c1.vue,例子是:然后,定义两个父子组件:c2.vuef1.vue
这样就可以在子组件中点击按钮触发listenerToC1事件,在监听这个事件父组件。其实和$emit触发事件类似,不同的是它可以嵌套多级,不一定是直接的父子组件就可以触发。4.sync修饰符在Vue1.x中,使用props进行“双向绑定”,实现父子组件通信。.sync修饰符用于将子组件中相应的prop值变化同步到父组件。但是,这打破了单向数据流,在2.0版本中被删除,并在2.3.0版本中以语法糖的形式添加。你可以看看文档中给出的例子