当前位置: 首页 > Web前端 > vue.js

Vue嵌套组件传参

时间:2023-03-31 14:32:16 vue.js

.btn_group{填充:20px10px;background-color:rgba(87,129,189,0.13);}本文以一个Vue递归组件为例,探讨多层嵌套后无法触发事件的问题。大家可以查看Demo,快速理解这个例子。假设我们已经知道Vue组件通常有父子组件通信和兄弟组件通信。父子组件通信非常简单。父组件会通过props将数据向下传递给子组件。当子组件有事情要告诉父组件时,它会通过$emit事件告诉父组件。那么当两个组件之间没有父子关系时,如何传递数据呢?先来看这个例子:递归嵌套组件传参我们封装了一个名为NestedDir(嵌套目录的意思)的子组件,内容如下(使用了元素ui组件):可以看出这个NestedDir从parent接收到嵌套数组类型的数据,其内部点击添加新的目录和文件可以触发parent级别监听的变化事件比较特殊的是这个组件调用了自己:但是需要注意的是,我们调用自己的时候,是notin是从里面监听change事件的,这也是为什么在二级目录下点击新建按钮无效的原因。我们传递给它的嵌套数据结构如下所示:[{"id":1,"name":"Directory1","type":"dir","children":[{"id":2,"name":"Directory3","type":"dir","children":[],"pid":1},{"id":3,"name":"File2","type":"file","pid":1}]},{"id":4,"name":"Directory2","type":"dir","children":[]},{"id":5、"name":"File1","type":"file","children":[]}]在父组件中调用NestedDir:.btn_group{填充:20px10px;background-color:rgba(87,129,189,0.13);}渲染出来的页面是这样的:深度递归组件??事件丢失我们构建了一个理论上可以无限嵌套的目录结构,但是经过测试,发现在二级目录上点击新建按钮没有反应是的,原因是我们在NestedDir中调用它,没有监听内部的change事件(上面提到过),所以无法触发父级的-如何解决父母的倾听事件?同样在递归调用的时候监听change事件,间接传递给最外层的组件(这是最容易想到的方法,但是如果组件嵌套很深,简直就是噩梦)EventBus(事件总线)什么是EventBus事件总线?它实际上是一个Vue实例,具有$emit、$on和$off方法,允许数据从一个组件传递到另一个组件而无需诉诸父组件。具体方法是在一个组件中$emit,在另一个组件中$on,可以这样操作://main.jsimportVuefrom'vue'importAppfrom'./App.vue'exportconsteventBus=newVue();//创建一个事件bus.newVue({render:h=>h(App),}).$mount('#app')这样,我们修改directory.vue,只需要更改srcipt部分:引入了import{eventBus}from"../main";在创建页面时添加事件监听器,并在页面销毁时移除事件监听器:created(){eventBus.$on('change',function(data){this.handleChange(data)})},destroyed(){eventBus.$off('change')}NestedDir.vue也需要做相应的改动,修改methods中的add方法即可:import{eventBus}from"../main";//...缩写方法:{add(el){//this.$emit('change',el)eventBus.$emit('change',el)}}这样,点击二级目录新建按钮,弹出框可以正常触发。上面的eventBus只在Vue2中有效,在Vue3中有效,$on,$off方法在Vue3中已经被移除,所以下一篇打算做一个Vue插件来处理类似Pub/Sub的这种情况。篇《EventBus 在vue的实现》