$attrs listeners

vue 通信方式:

  • Prop(常用)
  • $emit (组件封装用的较多)
  • .sync语法糖 (较少)
  • $attrs & $listeners (组件封装用的较多)
  • provide & inject (高阶组件/组件库用的较多)
  • slot-scope & v-slot (vue@2.6.0+)新增
  • scopedSlots 属性
  • 其他方式通信

使用v-bind="$attrs"将父组件中不被认为props特性绑定的属性传递给子组件。

**attrs**:包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind=”attrs” 传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。

**listeners**:包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on=”listeners” 传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。

通常该方法会配合interiAttrs一起使用。之所以这样使用是因为两者的出现使得组件之间跨组件的通信在不依赖Vuex和eventBus的情况下变得简洁,业务清晰。

  • ComponentA >
    • ComponentB >
      • ComponentC

$attrs 在组件A 传递时,组件B 并未接收到,会存在此中

javaScript

ComponentA

<template>
  <div class="nav">
    <h2>{{ ps }}</h2>
    <h5>nav compoments 第一级组件</h5>
    <NChild :name="name" :age="age" :cmsg="fam" @upAge="updateAge"></NChild>
  </div>
</template>
<script>
// @ is an alias to /src
import NChild from "./NChild.vue";
export default {
  name: "Nav",
  props: {
    ps: String,
  },
  data() {
    return {
      name: "Lily",
      age: 22,
      fam: "one msg",
      hello: "world",
    };
  },
  components: {
    NChild,
  },
  methods: {
    updateAge() {
      console.log('update age')
      this.age += this.age;
    },
  },
  mounted() {},
};
</script>


ComponentB

<template>
  <div class="navc">

     
    <h3>NChild 第二组件 --> {{cmsg}}   attrs:{{ $attrs }}  </h3>
    <n-childt v-bind="$attrs" v-on='$listeners'  />
  </div>
</template>
<script>
// @ is an alias to /src
import nChildt from './NChildt.vue'
export default {
  name: "NChild",
   props:{
     cmsg:String
   },
  data() {
    return {
      lusifer:'sfdsfdsfdf'
    };
  },
  components:{
    nChildt
  },
  methods: {},
  mounted() {
    // {name: "Lily", age: 22}   this.$listeners  upAge
    // 结果: {name: "Lily", age: 22} , 因为父组件共传来name, age, cmsg 三个值,由于 cmsg 被 props接收了,所以只有age, name属性
      console.log(this.$attrs, this.$listeners)
  },
};
</script>

ComponentC

<template>
  <div class="navcs">

     
    <h3>第三 组件 ---> {{age}} </h3>
      <el-button type="primary" icon="el-icon-edit" circle @click="updateF"></el-button>
  </div>
</template>
<script>
// @ is an alias to /src

export default {
  name: "NChildt",
  props:{
    age:Number
  },
  data() {
    return {};
  },
  methods: {
    updateF(){
      this.$emit('upAge') // 可以触发 ComponentA 组件中的 upAge 函数
    }
  },
  mounted() {
     console.log(this.$attrs,'第三个组件')
  },
};
</script>