认识vue的$attrs和$listeners

186 阅读1分钟

官方定义

vm.$attrs

  • 类型:{ [key: string]: string }
  • 只读
  • 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

vm.$listeners

  • 类型:{ [key: string]: Function | Array }
  • 只读
  • 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

使用场景

A组件->B组件->C组件

如果C组件想获取A组件的数据,有两种方法: 1.使用vuex(大材小用) 2.props传递(逐层传递,过于繁琐)

综上所述:这种场景,使用 "attrs和listeners"更合适

父组件(home.vue)
<template>
  <div>
    <aa test1="1" test2="2" @abc="abc"></aa>
  </div>
</template>

<script>
import aa from './aa.vue';
export default {
  name: 'Home',
  components: {
    aa
  },
  methods: {
    abc(value) {
      console.log('value',value)  // 监听到来自孙子组件
    }
  }
}
</script>
子组件(aa.vue)
<template>
    <div class="aa">
        <bb v-bind="$attrs" v-on="$listeners"></bb>
    </div>
</template>

<script>
import bb from './bb.vue';
export default {
    inheritAttrs: false, //默认值为true,为true时,会显示下面红圈标记内容
    components:{
        bb
    }
}
</script>
孙子组件(bb.vue)
<template>
    <div class="bb">
        {{$attrs.test2}}
        <div @click="btn">btn</div>
    </div>
</template>

<script>
export default {
    inheritAttrs: false, // 默认值为true,为true时,会显示下面红圈标记内容
    created() {
        console.log(this.$attrs) // {test1: "1", test2: "2"}
        console.log(this.$listeners) // {abc: ƒ}
    },
    methods: {
        btn () {
            this.$emit('abc','来自孙子组件') // 触发父组件监听(home.vue),把数据传给home.vue组件
        }
    }
}
</script>

inheritAttrs的默认值为true, 将inheritAttrs的值设为false, 这些默认的行为会禁止掉。但是通过实例属性$attrs ,可以将这些特性生效,且可以通过v-bind 绑定到子组件的非根元素上。 感觉还是挺晦涩难懂的,简单的说就是 inheritAttrs:true 继承除props之外的所有属性;inheritAttrs:false 只继承class属性。