16. Vue2.4+新增属性$attrs
vm.$attrs简介
首先我们来看下vue官方对vm.$attrs的介绍:
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建更高层次的组件时非常有用。
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建更高层次的组件时非常有用。
场景
vue中一个比较令人烦恼的事情是属性只能从父组件传递给子组件。这也就意味着当你想向嵌套层级比较深组件数据传递,只能由父组件传递给子组件,子组件再传递给孙子组件。<template> <div class="home"> <mytest :title="title" :massgae="massgae"></mytest> </div> </template> <script> export default { name: 'home', data () { return { title:'title1111', massgae:'message111' } }, components:{ 'mytest':{ template:`<div>这是个h1标题{{title}}</div>`, props:['title'], data(){ return{ mag:'111' } }, created:function(){ console.log(this.$attrs)//注意这里 } } } } </script>

继承父组件没有使用的属性,就算当前组件没有通过props传递进来,当前组件依然可以通过$atrrs取到message的值。
意思就是:$attrs
可以收集父组件中的所有传过来的属性除了那些在组件中没有通过 props
定义的。
案例1.
首先我们有三个组件A-B-C,然后想A中的属性传入C中,基本的做法是这样的,一层一层通过 props
往下传递
<script> let vm = new Vue({ el: '#app', data: { msg: '100' }, components: { 'ComponentB': { props: ['msg'], template: `<div>B<component-c :msg="msg"></component-c></div>`, components: { 'ComponentC': { props: ['msg'], template: '<div>C{{msg}}</div>' } } }, } }) </script>
ComponentB
组件中并没有使用到父组件传递过来的属性 msg
,但是这样写就是想把属性再传递给ComponentC
,那么除了这种写法还可以给ComponentC
绑定$attrs
属性。
<script> let vm = new Vue({ el: '#app', data: { msg: '100' }, components: { 'ComponentB': { template: `<div>B<component-c v-bind="$attrs"></component-c></div>`, components: { 'ComponentC': { props: ['msg'], template: '<div>C{{msg}}</div>' } } }, } }) </script>
$attrs
可以很方便的做到属性透传,使用起来也比较简单,避免了多写 props
的痛苦。面试的时候也经常会问到父子组件通讯的方式有哪些,那么 props
和 $attrs
都是可以的。
案例2
父组件:
<template> <div> <child-dom :foo="foo" :coo="coo" > </child-dom> </div> </template> <script> import childDom from "./child1"; export default { data() { return { foo:"Hello, world", coo:"Hello,rui" } }, components:{childDom}, } </script>
子组件:
<template> <div> <p>foo:{{foo}}</p> </div> </template> <script> export default { name:'child-dom', props:["foo"] } </script>
父组件的Dom结构
在子组件中加入inheritAttrs后,在2.4中新增选项inheritAttrs inheritAttrs的默认值为true, 将inheritAttrs的值设为false, 这些默认的行为会禁止掉。但是通过实例属性$attrs ,可以将这些特性生效,且可以通过v-bind 绑定到子组件的非根元素上。
父组件的dom结构图:
修改子组件:
<template> <div> <p>foo:{{foo}}</p> <p>attrs:{{$attrs}}</p> </div> </template> <script> export default { inheritAttrs:false, name:'child-dom', props:["foo"] } </script>
参考:https://www.jianshu.com/p/ce8ca875c337
参考:https://blog.csdn.net/weixin_34062329/article/details/88066389
不要小瞧女程序员
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具