zoukankan      html  css  js  c++  java
  • vue中使用v-bind="$attrs"和v-on="$listeners"进行多层组件监听

     

      vue组件之间通信,我们可以使用props和vuex两种方式,但是vuex太重,props在多级组件中使用又太麻烦,vue2.4版本提供了另一种方法,使用v-bind="$attrs",将父组件中不被认为 props特性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起使用。

     

     

    例如下面的层级关系

    <top>
      <center>
        <bottom>
        </bottom>
      </center>
    </parent>

    如果top组件要和bottom组件进行通信,下面有三种方式可以实现

      1.通过props和$emit的方式,需要通过center作为中转,top把值传给center,center再把值传给bottom,或者bottom把值传给center,center在传给top

      2.使用vuex,但是这两个组件的状态可能不是全局状态

      3.使用中央事件总线bus

    使用前两种方式可能都不太理想,这里来讲一下另一种方式

     

      先看一下代码片段

    top组件,传递了name,age,gender,sdf四个属性到子组件center,然后接收了两个isClick()和asd()方法

    <template>
      <section>
        <centers
          name="name"
          age="18"
          gender="666"
          sdf="asd"
          @isClick="isClick"
          @asd="asd"
        ></centers>
      </section>
    </template>
    <script>
      import centers from '~/components/center';
      export default {
        components: {
          centers
        },
        methods: {
          asd() {
            console.log(999);
          },
          isClick() {
            console.log(666);
          }
        }
      };
    </script>

     

     

    center组件,只接收了name和age两个属性,其他属性没有接收,使用 v-bind="$attrs" 属性,vm.$attrs 是一个属性,其包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。这些未识别的属性可以通过 v-bind="$attrs" 传入内部组件。未识别的事件可通过v-on="$listeners"传入(.native绑原生事件是没用的)。

    <template>
      <section>
        <div class="mt-10">
          <bottom v-bind="$attrs" v-on="$listeners" />
        </div>
      </section>
    </template>
    
    <script>
      import bottom from '~/components/bottom';
      export default {
        components: {
          bottom
        },
        props: {
          name: {
            type: String,
            default: 'default'
          },
          age: {
            type: String,
            default: 'default'
          }
        }
      };
    </script>

     

    bottom组件,我们只接收了gender属性,但是这个属性是其父组件center使用 v-bind="$attrs" 从top组件接收到的,center组件本身并没有使用props接收这个属性,但是bottom属性确可是使用

    <template>
      <section>
        <div>
          {{ $attrs['gender'] }}  在$attrs里面只会有props没有注册的属性
          <br>
          {{ gender }}
        </div>
      </section>
    </template>
    
    <script>
      export default {
        props: {
          gender: {
            type: String,
            default: ''
          }
        },
        mounted() {
          console.log(this.$attrs);
          console.log(this.$listeners);
          this.$listeners.isClick();
          this.$listeners.asd();
        }
      };
    </script>

     

     

    总结

    1.v-bind="$props": 可以将父组件的所有props下发给它的子组件,子组件需要在其props:{} 中定义要接受的props。

      vm.$props: 当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。

     

    2.v-bind="$attrs": 将调用组件时的组件标签上绑定的非props的特性(class和style除外)向下传递。在子组件中应当添加inheritAttrs: false(避免父作用域的不被认作props的特性绑定应用在子组件的根元素上)。

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

     

    3.v-on="将父组件标签上的自定义事件向下传递其子组件可以直接通过emit(eventName)的方式调用。

      vm.$listeners: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

     

    4.举例说明:

      4.1.如上实例代码中,top组件传值给center可以全部不接收,然后直接通过 v-bind="$attrs" 传给bottom,然后bottom组件直接使用props接收top传过来的所有属性

      4.2.在别人组件的基础上进行二次封装的时候,定义好自己的属性,然后在自己的组件上直接传值,然后通过 v-bind="$attrs" 把值传给别人的组件即可,例如

    <template>
      <div>
        <el-button v-bind="$attrs">确定</el-button>
      <div>
    </template>
     
    // 父组件使用
    <my-button type='primary' size='mini'/>

     

    5.vm.$attrs和vm.$listeners获取到的值都是json的形式,对应每一个属性和取值,可以直接使用实例验证一下~

     

     

    嗯,就酱~~~

  • 相关阅读:
    【Codechef】Chef and Bike(二维多项式插值)
    USACO 完结的一些感想
    USACO 6.5 Checker Challenge
    USACO 6.5 The Clocks
    USACO 6.5 Betsy's Tour (插头dp)
    USACO 6.5 Closed Fences
    USACO 6.4 Electric Fences
    USACO 6.5 All Latin Squares
    USACO 6.4 The Primes
    USACO 6.4 Wisconsin Squares
  • 原文地址:https://www.cnblogs.com/jin-zhe/p/13099416.html
Copyright © 2011-2022 走看看