vue的$listeners与$attrs 简单理解

1,249 阅读2分钟

A组件中的数据

<template>
  <div>
    <h1>我是父组件 向下传了三个值 foo coo list</h1>
    <h1 style='width:300px'>vue2.4版本新增了$listeners 属性,我们在b组件上 绑定 v-on=”$listeners”, 
    在a组件中,监听c组件触发的事件。就能把c组件发出的数据,传递给a组件。</h1>
    <div v-if="obj">
      我接收到C组件中传过来的数据并显示===》
      <el-tag type="danger" closable>{{obj}}</el-tag>
    </div>
    <B :foo="foo" :coo="coo" :list="list" @upRocket="reciveRocket"></B>
  </div>
</template>

<script>
import B from "@/components/commons/B";
export default {
  name: "A",
  components: {
    B
  },
  data() {
    return {
      foo: "Hello, foo",
      coo: "Hello,coo",
      list: [{ value: 1, laber: "我是1" }, { value: 2, laber: "我是2" }],
      obj: ""
    };
  },
  methods: {
    reciveRocket(val) {
      this.obj = val;
    }
  }
};
</script>

<style>
</style>

B组件中的数据

<template>

   <div class="b">
     <h1>B组件中的数据</h1>
     <h1 style='width:300px'>在2.4中新增选项inheritAttrs  inheritAttrs的默认值为true,
       将inheritAttrs的值设为false, 这些默认的行为会禁止掉。
       但是通过实例属性$attrs ,可以将这些特性生效,
       且可以通过v-bind 绑定到子组件的非根元素上。</h1>
     <h2 style='width:300px'>如果在子组件内将 inheritAttras 选项设置为 false ,我们能够通过 $attrs 这个属性拿到组件 props 中没有定义但是父组件中有传递的属性值:, 作为中间传递数据的组件,必须要把 inheritAttrs 这个选项设置为 false 才能正确获取 $attrs 数据。 同时  如果在中间组件中运用了当前父组件传下来的数据时,孙组件是不能通过$attrs 拿到这个数据的 除非中间件通过子传父把当前的属性传递下去</h2>
     <h3 style='width:300px'> B 组件要通过  v-bind="$attrs" (向下传递数据)  把当前数组件中的数据传递到C组件中  这时C组件可以通过 this.$attrs  获取当前A组件中传递下来的值(获取到的是B组件没有接收使用过的值)   </h3>
       <h3 style='width:300px'> B 组件要通过  v-on="$listeners" (向下传递方法,通过手动去调用 $listeners 对象里的方法,来触发从父级接受来的函数。)  这时C组件中可以通过 " this.$listeners.A组件向下传递的方法名称(传递的值) " 来向上传递数据     </h3>
      <p>我是B组件从A组件接收过来的的foo:{{foo}}</p>
      <p>我是B组件中通过$attrs获取的数据父组件中数据:{{$attrs}}</p>
      <C v-bind="$attrs" :foo='foo' v-on="$listeners"></C>
 </div>
</template>

<script>
import C from "@/components/commons/C"
export default {
  name:'B',
  components:{
    C
  },
  props:["foo"],
  inheritAttrs:false,  
  //如果在子组件内将 inheritAttras 选项设置为 false ,我们能够通过 $attrs 
  这个属性拿到组件 props 中没有定义但是父组件中有传递的属性值:,
  作为中间传递数据的组件,必须要把 inheritAttrs 这个选项设置为 false 才能正确获取 $attrs 数据。
  同时  如果在子组件中运用了当前父组件传下来的数据时,孙组件是不能通过$attrs 拿到这个数据的 除非中间件通过子传父把当前的属性传递下去 ( :foo='foo')

}
</script>

<style>
.b{
  background: blanchedalmond;
}
</style>

C组件中的数据

<template>
  <div class="c">
    <h1>我是C组件中的数据</h1>
    <p>从A组件中接收来的coo:{{coo}}</p>
    <p>B组件父传子传下来的foo:{{foo}}</p>
    <!-- <p>获取到listenersOrAttrs组件中伟过来的数据list===={{list}}</p> -->
    <p>从listenersOrAttrs(A)组件中伟过来的数据通过$attrs获取list===={{$attrs.list}}</p>
    <el-input style="width:200px;" v-model="listData" placeholder="请输入数据" @change="startEmit"></el-input>

    <button @click="startEmit">确定</button>
  </div>
</template>
<script>
export default {
  name: "C",
  props: ["coo","foo"],   //如果引用了 listenersOrAttrs 组件传过来的数据 在 $attrs中就获取不到了  如果list如果引用了  $attrs中是就空的数据了
  inheritAttrs:true,
  data() {
    return {
      listData: ""

    };
  },
  created() {
    console.log(this.$attrs);
  },
  methods: {
    startEmit() {
      this.$listeners.upRocket(this.listData) // 方法1  通过this.$listeners传给listenersOrAttrs组件值
      // 方法2   this.$emit("upRocket", this.listData);
    },

  }
};
</script>
<style>
.c {
  background: lawngreen;
}
</style>


这些是我看过一些不错的文档之后自己整理后的理解,请求各位大佬们进行指点