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公众号:程序员付杰 ,一起学习编程技能

相关推荐
匹马夕阳22 分钟前
Vite项目中vite.config.js中为什么只能使用process.env,无法使用import.meta.env?
开发语言·前端·javascript
只有一斤了呐27 分钟前
超硬核!教你手搓一套船新架构的前端脚手架~
前端·javascript·开源
拉不动的猪30 分钟前
刷刷题38(前端实现分包及组件懒加载的核心方案&&图片懒加载)
前端·javascript·面试
任磊abc39 分钟前
在react当中利用IntersectionObserve实现下拉加载数据
前端·react·observer·下拉加载·intersection
NaZiMeKiY39 分钟前
HTML5前端第三章节
前端·html·html5
Loadings1 小时前
Cursor内置的系统提示词学习
前端·javascript·cursor
拉不动的猪1 小时前
前端数据库indexDB
前端·javascript·面试
自学前端_又又1 小时前
前端苦熬一月,被 Cursor 5 天超越,未来技术浪潮如何破局?
前端·人工智能·cursor
冴羽1 小时前
SvelteKit 最新中文文档教程(4)—— 表单 actions
前端·javascript·svelte
搬砖-无恙1 小时前
vue uniapp里照片多张照片展示
前端·vue.js·uni-app