Vue 透传实战: 如何用 $attrs 和 v-bind 提升代码效率

前言

相信大家在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 数据透传给后代组件了呢。

总结

通过 $attrsv-bind,我们可以轻松实现 Vue 组件的透传功能,同时利用 inheritAttrs 和对象绑定优化开发体验。这种技巧不仅提升了代码的灵活性,还能减少手动操作的繁琐,让组件间的数据传递更加高效和可控。

如果觉得本文对你有帮助,希望能够给我点赞支持一下哦 💪 也可以关注wx公众号:程序员付杰 ,一起学习编程技能

相关推荐
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼5 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
草梅友仁5 小时前
草梅 Auth 1.4.0 发布与 ESLint v9 更新 | 2025 年第 33 周草梅周报
vue.js·github·nuxt.js
ZXT5 小时前
promise & async await总结
前端
Jerry说前后端5 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化