16. Vue2.4+新增属性$attrs

vm.$attrs简介

首先我们来看下vue官方对vm.$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

原文地址:https://www.cnblogs.com/shix0909/p/11217789.html