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的形式,對應每一個屬性和取值,可以直接使用實例驗證一下~

 

淶源:https://www.cnblogs.com/jin-zhe/p/13099416.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM