Vue - 组件通信之$attrs、$listeners

2022-02-25  本文已影响0人  Petricor

前言

vue通信手段有很多种,props/emit、vuexevent bus、provide/inject 等。还有一种通信方式,那就是 $attrs$listeners,这种方式很优雅,使用起来也不赖。下面例子都会通过父(index)、子(child)、孙子(grandson),三者的关系来说明使用方式。

组件关系图

$attrs

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

我的理解:
接收除了props声明外的所有绑定属性(class、style除外)

index.vue
    <child class="arrts"  id="10"   age="20"  sex="男" ></child>
   <!--在 子组件中展示 $arrts:{  "age": "20",  "sex": "男" } ;class和style 特殊的不会被绑定 -->
child.vue
<template>
  <div class="attrs-one-view">
    <p>$arrts:{{ $attrs }}</p>  <!-- {  "age": "20",  "sex": "男" }  -->
    <div>prop->id: {{ id }}</div> <!-- 10  -->
  </div>
</template>
<script>
export default {
  props: {
    id: {
      type: String,
    },
  },
};
</script>

图解:

父子传值

解释:
由于child.vue 在 props 中声明了 id 属性,$attrs 中只有age、gender两个属性,输出结果为:
{ "age": "20", "sex": "男" }
$attrs 里面接收的是 除了porps里面定义属性之外的值


child.vue -> grandson.vue

$listeners

如果$attrs 是操作父子传参的,那$listeners就是操作父组件传递子组件方法的

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

我的理解

index.vue
<template>
 <child  @getInfo="getInfo"  @getMessage.native="getMessage"></child>
</template>
<script>
export default {
  components: { child, },
  methods: {
    getInfo(val) {
      console.log("getInfo事件来源于index.vue" + val);
    },
    getMessage(val) {
      console.log("getMessage事件来源于index.vue" + val);
    },
  },
};
</script>
child.vue
<template>
  <div class="child-view">
    <grandson v-on="$listeners" @getMessage="getMessage" ></grandson> 
  </div>
</template>
<script>
export default {
  components: { grandson, },

  created() {
      console.log(this.$listeners, '====listeners'); 
  },
};
//打印结果: 因为在index.vue中getMessage有native修饰,所以不会触发
// {getInfo: ƒ}getInfo: ƒ invoker()[[Prototype]]: Object '====listeners'
grandson.vue
<script>
export default {
  created() {
    console.log(this.$listeners, "====listeners");
  },
};
</script>

//打印结果:
// {getInfo: ƒ, getMessage: ƒ}getInfo: ƒ invoker()getMessage: ƒ invoker()[[Prototype]]: Object '====listeners'
$listeners 事件监听

代码地址:码云 vue-question 组件通讯
参考文档:Vue - 组件通信之attrs、listeners

上一篇下一篇

猜你喜欢

热点阅读