前言

今天在开发的时候,发现同事用到了$attrs和$listeners,因为此前本人用的很少,所以就去研究了一下,总的来说这两个api就是用来进行组件之间通信的,只不过不用像props和$emit传值t通信那样繁琐,缺点就是不好维护,可读性比较低,因此我们在项目中用的比较少,如果需要跨多个组件通信也会选择Vuex

主要内容

  1. 先来看$attrs和$listeners的定义在Vue文档中:
  • vm.$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
  • $listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
再来写个Demo
<template>  <div id="app"><Child1 :words1="text1" :words2="text2" :words3="text3" v-on:event1="goEvent1" v-on:event2="goEvent2"></Child1>
  </div></template><script>import Child1 from "./components/Child1"export default {  name: "App",  data() {return {      text1: 1,      text2: 2,      text3: 3}
  },  methods: {goEvent1() {      console.log("child 提交成功")
    },goEvent2(value) {      console.log(value)
    }
  },  components: {
    Child1,
  }
}</script><style>html,body {  height: 100%;
}#app {  height: 100%;
}</style>复制代码
<template>  <div class="mainWrapper"><p>props: {{words1}}</p><p>$attrs: {{$attrs}}</p><button @click="submit()">提交</button><hr><child2 v-bind="$attrs" v-on="$listeners"></child2><!-- 通过$listeners将父作用域中的v-on事件监听器,传入child2,使得child2可以获取到app中的事件 -->
  </div></template><script>import Child2 from "./Child2"export default {  name: "Child1",  props: ["words1"],  data() {return {}
  },  inheritAttrs: true,  components: { Child2 },  methods: {submit() {      this.$emit("event1", "child1 提交事件")
    }
  }
}</script><style scoped>.mainWrapper {  height: 100px;
}</style>复制代码
<template>  <div><div class="child-2">  <p>props: {{words2}}</p>  <p>$attrs: {{$attrs}}</p>  <input v-model="inputValue" name="" id="" @input="goInput"></div>
  </div></template><script>export default {  name: 'Child2',  props: ['words2'],  data() {return {      inputValue: ''};
  },  inheritAttrs: false,  mounted() {
  },  methods: {
    goInput () {      this.$emit('event2', this.inputValue);
    }
  }
}</script>复制代码
  • Child2.vue
  • Child1.vue
  • App.vue
效果
  • 可以看到父组件App.vue中通过v-bind给Child1传递了三个值,在子组件中未被Props接收的值都在$attrs中,其也可以通过v-bind将值传递给Child1的内部组件Child2,同时也可以使用$listeners将父作用域中的v-on事件监听器,传入child2
inheritAttrs 属性以及作用
  • 当一个组件设置了inheritAttrs: false后(默认为true),那么该组件的非props属性(即未被props接收的属性)将不会在组件根节点上生成html属性,以为为对比图

inheritAttrs:false

$attrs和$listeners,inheritAttrs的使用_$listeners

inheritAttrs:true       
复制代码

$attrs和$listeners,inheritAttrs的使用_$attrs_02