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

vue多层嵌套组件传值

时间:2023-03-31 23:50:31 vue.js

说到vue组件传值,大致分为以下几种情况:1.父组件通过属性绑定给子组件传值,子组件通过props2接收。父组件通过v-on监听方法从子组件传递给父组件,子组件通过$emit触发父组件的方法,将数据传递给父组件作为回调函数的参数。3.兄弟组件通过on和emit机制定义一个eventBus传值,实现事件的绑定和触发,实现数据的流转。现在普遍使用vuex来实现数据的共享和流转。多层嵌套组件传值问题说明:另外,今天遇到一个情况。组件A、B、C、D之间是嵌套关系,即组件A>组件B>组件C>组件D,但是组件D要触发组件A中的方法,因为设计的数据不是一开始放到vuex里面,是对公共组件的封装,不适合放到vuex里面。我也在vue的官网上看了。我看到了inheritAttrs属性。一开始没看懂文档描述的意思。后来看到一篇关于vue的多层嵌套传值在segmentfault中的文章。借助里面的demo和vue官网,我终于好像明白了多层嵌套传值的意义。方案开始的时候,我也考虑过子组件层层发射,直到A组件监听到这个事件。但是考虑到组件B和组件C并没有使用这个方法作为中间组件,我们简单的定义一个方法来向上层组件发射数据。每一层组件都需要实现时间监控。这个方法按道理也是可以实现的,但是总觉得这个方法有点笨。我想将此方法用作planB。先试试看。如果你找不到合适的解决方案,那就采用这个方案。我想实现的方案很简单,就是D可以触发A中的方法,但是中间组件不需要帮忙传递。在解决问题之前,首先需要了解一下Vue官网的几个概念。inheritAttrs默认情况下,父作用域中不被视为props的属性绑定将“回退”并作为普通的HTML属性应用在子组件的根元素上。当组成一个包装一个或另一个目标元素的组件时,这可能并不总是像预期的那样表现。通过将`inheritAttrs`设置为`false`,这些默认行为将被删除。这些属性可以通过(在2.4中也是新的)实例属性`$attrs`生效,并且可以通过`v-bind`显式绑定到非根元素。一开始看了两遍,没看懂inheritAttrs的描述(理解能力真的有点差)。我个人的理解是这样的。如果组件A引用组件B,组件A是父组件,组件B是子组件,组件A通过属性绑定传值给组件B,组件B通过props接收,当然组件B只会接受它的属性需要。如果组件B不需要name属性,但是组件A想传给组件B,但是组件B没有在props中接收到,那么这个value肯定是传入了,但是传到哪里去了,然后再次阅读这段话,“父作用域中不被视为props的属性绑定将“回退”并作为普通HTML属性应用于子组件的根元素。”,这意味着name属性不是在props中接受的话,会自动绑定到B组件的根组件上。但是既然B组件没有在props中接收到,那肯定是没用的,所以肯定不会想到会发生这样的事情,“通过设置inheritAttrs为false,这些默认行为就会被移除”。最初设置为false是为了防止这种行为。回到我们的需求,组件B和组件C是一个中间组件,不需要接收。您可以将inheritAttrs设置为false以实现vm.$attrs包含那些在父作用域属性绑定(类和样式除外)中未被识别(和获取)为props的属性。当一个组件没有声明任何props时,所有的父作用域绑定(除了class和style)都会被包含在这里,内部组件可以通过v-bind="$attrs"传入——在创建高级组件时非常有用。父组件传值给子组件,子组件通过prop接收一部分,但是没有接收到的那部分怎么获取呢,哈哈,是通过$attrs。里面包含了父作用域的所有绑定,划重点!!!,你可以把v-bind="$attrs"传到内部组件里,离事件监听还远着呢!!!$listeners包含父作用域中的v-on事件监听器(没有.native装饰器)。它可以通过v-on="$listeners"传递给内部组件——在创建更高级别的组件时很有用。对,没错,他来了,把v-on="$listeners"传入内部组件!!!理解了这三个概念,我的问题就迎刃而解了。总结1.如果要在D中触发A中的handlePreview方法,首先组件A监听该方法2.在组件B和组件C中设置inheritAttrs为false,不接收,然后向内部组件发送数据和事件Pass(我这次只需要methods,不需要属性,所以为了加深学习印象,一起传了v-bind="$alert")3.在D组件中,通过$emit触发A组件中的方法,成功完成我的需求。以下内容是一个代码片段(vue语法),大致表达了大概的意思。参考文章链接:vue多级嵌套组件传参A组件B组件C组件D组件script>exportdefault{name:'c-component',methods:{handleClick(){this.$emit('handlePreview')}}}