前言
相信大家在Vue的面试中,会经常被问到这样一个问题:Vue 有那些组件传参的方式?
我相信,这个问题对你来说一定不在话下!你可能已经能轻松列出个123等很多组件传参方式了。
而我今天要聊的正是其中一种实用传参方式:利用v-bind
和$attrs
实现数据透传!对于其中的v-bind
的基本使用这里就不过阐述了。如果你还不了解的话,可以阅读一下Vue 官网或去我 vue 专栏阅读相关内容。
1. $attrs 简单回顾
对于attrs
相信大家都不会陌生!在 Vue 中,当父组件通过子组件的标签属性传递数据时,子组件内部是这么处理的:
如果子组件用props
声明了接收这些数据,这些数据就会被记录在组件实例的$props
属性中;而那些子组件没有通过props显式接收的数据, 则会收集到$attrs
属性中。
例如: 当我们在App
组件中按照如下方式给子组件Parent
传参数时:
在Parent
组件中, 通过props 显示接收msg
数据
从上面的示例可以看出,只有那些子组件没有通过props显式接收的父组件参数,才会被记录在子组件实例的$attrs中。
2. $attrs 默认透传机制
还不止这些!其实 Vue 还默认地为$attrs
设计了一个默认的透传机制,也就是说,如果子组件只有一个根标签,那么$attrs
中的所有属性会自动绑定到这个根标签上。
例如上例中$attrs
中的属性就会自动渲染的根标签上。如下:
这样处理的好处就是能够很好的将父组件传入了class、style或者自定义属性,自动合并到子组件根标签上。
到了此刻, 大家不妨试想一下,如果子组件也有自己的子组件。 例如Parent
组件如下:
此时App
组件传入$attrs
会自动添加到根标签上, 而根标签却是一个组件标签。
如果显示的写出来是不是就向下面代码一样。 而这种方式不就意味着Parent
组件将自己的$attrs
数据直接传给了Child
组件。 这不就间接实现了App
组件 向 孙组件Child
透传数据。
当然啦,$attrs
的这种默认透传方式虽然很方便,但也存在局限性。
首先这个机制只有在子组件只有一个根标签的情况下才会生效。如果子组件有多个根标签,Vue 就不知道应该把$attrs
绑定到哪个标签上了,这时候透传就会失败。
其次就是孙组件标签必须是根标签, 如果给孙组件套一层根标签, $attrs
会绑定在根标签上, 而不是绑定在孙组件标签上。此时透传也会失败。
示例:
所以,虽然$attrs
的默认透传真的很贴心,但在一些特殊场景下,透传将会失效。因此我们就需要手动处理透传。
3. 手动实现透传
所谓的手动实现透传, 就是将$attrs
数据手动绑定到孙组件标签上。
诶,虽然咱们已经实现了透传,但仔细想想,其实还是会有两个小问题需要注意的。
这第一个问题,就是$attrs
的默认绑定机制还在。简单来说,就是$attrs
的数据既会绑定到子组件的根标签上,又会继续透传给孙组件。这就意味着,有时候你可能会发现根标签上多了些你并不想要的属性,虽然不会直接影响功能,但看起来总感觉很"多余"。
第二个问题,就是当需要透传的$attrs
数据特别多的时候,手动一个个去绑定就有点麻烦了。而且,如果后续透传的数据发生了变化,那所有相关的透传线路都得手动调整,这工作量简直让人头大啊!
其实啊,针对上面提到的那两个问题我们是有方法解决的。
4. inheritAttrs
针对第一个问题,如果咱们不想要$attrs
自动绑定到根标签上,我们就可以使用 inheritAttrs
选项。inheritAttrs
选项是 Vue 提供的用来控制是否启用默认的透传行为。如果咱们把这个选项的值改成 false,那么Vue 就不会将 $attrs
自动绑到根标签上。
当我们将inheritAttrs
选项设置为false
后, Parent
组件的根标签将不会绑定$attrs
数据
5. v-bind 指令
针对第二个问题,咱们就得搬出 v-bind 指令啦!
关于 v-bind
指令,相信大家都不会陌生吧?它的主要作用就是 动态绑定属性值。不过,除了咱们常用的"单个属性绑定"之外,v-bind 其实还可以接收一个对象作为参数,这样就可以 一次性绑定多个属性 啦!
示例:
渲染完成后,咱们就能看到 user 对象里的每个属性,都被动态地绑定到对应的标签上了!
其实这种传对象的用法也是我们平时很容易忽略的用法。
至此我相信你已经明白了, 我们就可以通过v-bind
和$attrs
组合使用, 实现自定义组件透传。
此时我们就可以通过v-bind
和$attrs
实现组件透传功能。 当然,大家不妨试想一下, 既然可以把$attrs
传给v-bind
实现透传。 那我们是不是也可以将$props
传给v-bind
实现props 数据转传给后代组件呢
这个时候,我们就可以利用 v-bind
和 $attrs
来实现 组件透传功能 了。说白了,就是把上级组件的属性一股脑儿地传递下去,完全不用咱们手动一个个写,是不是很省事儿?
那问题来了,既然咱们能把 $attrs
传给 v-bind
实现透传,那 $props
是不是也可以这么玩呢?想象一下,如果我们把 $props
也传给 v-bind
,那是不是就能直接把父组件传递的 props 数据透传给后代组件了呢。
总结
通过 $attrs
和 v-bind
,我们可以轻松实现 Vue 组件的透传功能,同时利用 inheritAttrs
和对象绑定优化开发体验。这种技巧不仅提升了代码的灵活性,还能减少手动操作的繁琐,让组件间的数据传递更加高效和可控。
如果觉得本文对你有帮助,希望能够给我点赞支持一下哦 💪 也可以关注wx公众号:
程序员付杰
,一起学习编程技能