欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中$attrs和$listeners詳解以及使用方法

 更新時(shí)間:2022年11月14日 11:09:50   作者:明天也要努力  
最近在研究Vue的組件庫(kù),之前也用過(guò)$attrs和$listeners,官方文檔描述的不太詳細(xì),也沒(méi)有太好的例子,下面這篇文章主要給大家介紹了關(guān)于Vue中$attrs和$listeners詳解以及使用的相關(guān)資料,需要的朋友可以參考下

Vue中 常見(jiàn)的組件通信方式可分為三類(lèi)

父子通信

父向子傳遞數(shù)據(jù)是通過(guò) props,子向父是通過(guò) events($emit);
通過(guò)父鏈 / 子鏈也可以通信($parent / $children);
ref 也可以訪問(wèn)組件實(shí)例;
provide / inject;
$attrs/$listeners;

兄弟通信

Bus;
Vuex;

跨級(jí)通信

Bus;
Vuex;
provide / inject、
$attrs / $listeners、

1. 前言

多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí),通常使用的方法是通過(guò) vuex。如果僅僅是傳遞數(shù)據(jù),而不做中間處理,使用 vuex 處理,未免有點(diǎn)殺雞用牛刀。

Vue 2.4 版本提供了另一種方法,使用 v-bind=”$attrs”, 將父組件中不被認(rèn)為 props 特性綁定的屬性傳入子組件中,通常配合 interitAttrs 選項(xiàng)一起使用。之所以要提到這兩個(gè)屬性,是因?yàn)閮烧叩某霈F(xiàn)使得組件之間跨組件的通信在不依賴 vuex 和 事件總線 的情況下變得簡(jiǎn)潔,業(yè)務(wù)清晰。

首先分析以下應(yīng)用場(chǎng)景

A 組件與 B 組件之間的通信: (父子組件)

如上圖所示,A、B、C三個(gè)組件依次嵌套,按照 Vue 的開(kāi)發(fā)習(xí)慣,父子組件通信可以通過(guò)以下方式實(shí)現(xiàn):

  • A to B 通過(guò) props 的方式向子組件傳遞,B to A 通過(guò)在 B 組件中 $emit, A 組件中 v-on 的方式實(shí)現(xiàn);
  • 通過(guò)設(shè)置全局 Vuex 共享狀態(tài),通過(guò) computed 計(jì)算屬性和 commit mutation 的方式實(shí)現(xiàn)數(shù)據(jù)的獲取和更新,以達(dá)到父子組件通信的目的;
  • Vue Event Bus,使用 Vue 的實(shí)例,實(shí)現(xiàn)事件的監(jiān)聽(tīng)和發(fā)布,實(shí)現(xiàn)組件之間的傳遞;

往往數(shù)據(jù)在不需要全局的情況而僅僅是父子組件通信時(shí),使用第一種方式即可滿足。

A 組件與 C 組件之間的通信: (跨多級(jí)的組件嵌套關(guān)系)

如上圖,A 組件與 C 組件之間屬于跨多級(jí)的組件嵌套關(guān)系,以往兩者之間如需實(shí)現(xiàn)通信,往往通過(guò)以下方式實(shí)現(xiàn):

  • 借助 B 組件的中轉(zhuǎn),從上到下 props 依次傳遞,從下至上 $emit 事件的傳遞,達(dá)到跨級(jí)組件通信的效果;
  • 借助 Vuex 的全局狀態(tài)共享;
  • Vue Event Bus,使用 Vue 的實(shí)例實(shí)現(xiàn)事件的監(jiān)聽(tīng)和發(fā)布,實(shí)現(xiàn)組件之間的傳遞

第一種通過(guò) props 和 $emit 的方式,使得組件之間的業(yè)務(wù)邏輯臃腫不堪,B組件在其中僅僅充當(dāng)?shù)氖且粋€(gè)中轉(zhuǎn)站的作用;
第二種 Vuex 的方式,某些情況下似乎又有點(diǎn)大材小用的意味(僅僅是想實(shí)現(xiàn)組件之間的一個(gè)數(shù)據(jù)傳遞,并非數(shù)據(jù)共享的概念);
第三種情況的使用在實(shí)際的項(xiàng)目操作中發(fā)現(xiàn),如不能實(shí)現(xiàn)很好的事件監(jiān)聽(tīng)與發(fā)布的管理,往往容易導(dǎo)致數(shù)據(jù)流的混亂,在多人協(xié)作的項(xiàng)目中,不利于項(xiàng)目的維護(hù);

$attrs 以及 $listeners 的出現(xiàn)解決的就是第一種情況的問(wèn)題,B 組件在其中傳遞 props 以及事件的過(guò)程中,不必在寫(xiě)多余的代碼,
僅僅是將 $attrs 以及 $listeners 向上或者向下傳遞即可。

2. 知識(shí)點(diǎn)

inheritAttrs:默認(rèn)值 true,繼承所有的父組件屬性(除 props 的特定綁定)作為普通的HTML特性應(yīng)用在子組件的根元素上,如果你不希望組件的根元素繼承特性設(shè)置 inheritAttrs: false ,但是 class 屬性會(huì)繼承。

(簡(jiǎn)單的說(shuō),inheritAttrs:true 繼承除 props 之外的所有屬性;inheritAttrs:false 只繼承 class style 屬性)

$attrs–繼承所有的父組件屬性(除了 prop 傳遞的屬性、class 和 style ),一般用在子組件的子元素上

$ listeners屬性,它是一個(gè)對(duì)象,里面包含了作用在這個(gè)組件上的所有監(jiān)聽(tīng)器,你就可以配合 v-on="$listeners" 將所有的事件監(jiān)聽(tīng)器指向這個(gè)組件的某個(gè)特定的子元素。(相當(dāng)于子組件繼承父組件的事件)

3. 示例

A組件(App.vue)

<template>
  <div id="app">
    <!-- 此處監(jiān)聽(tīng)了兩個(gè)事件,可以在B組件或者C組件中直接觸發(fā) -->
    <child1  :pchild1="child1" :pchild2="child2" :pchild3="child3" @method1="onMethod1" @method2="onMethod2"></child1>
  </div>
</template>

<script>
import Child1 from "./Child1.vue";
export default {
  data() {
    return {
      child1:'1',
      child2: 2,
      child3:{
        name:'child3'
      }
    };
  },
  components: { Child1 },
  methods: {
    onMethod1(msg1) {
      console.log(`${msg1} running`);
    },
    onMethod2(msg2) {
      console.log(`${msg2} running`);
    },
  },
};
</script>

B組件(Child1.vue)

<template>
  <div class="child-1">
    <h2>in child1</h2>
    <p>props: {{ pchild1 }}</p>
    <p>$attrs: {{ $attrs }}</p>
    <hr/>
    <!-- 通過(guò) v-bind 綁定$attrs屬性,C組件可以直接獲取到A組件中傳遞下來(lái)的props(除了B組件中props聲明的) -->
    <!-- C組件中能直接觸發(fā)test的原因在于 B組件調(diào)用C組件時(shí) 使用 v-on 綁定了$listeners 屬性 -->
    <child2 v-bind="$attrs" v-on="$listeners"></child2>
  </div>
</template>

<script>
import Child2 from "./Child2.vue";
export default {
  data() {
    return {
      child1:'child1'  
    };
  },
  components: { Child2 },
  props: {
    pchild1:{
      type:String
    }
  },  
  inheritAttrs: false,
  mounted() {
    this.$emit("method1",this.child1);
  },
};
</script>

C 組件 (Child2.vue)

<template>
  <div class="child-2">
    <h2>in child2:</h2>
    <p>props: {{ pChild2 }}</p>
    <p>$attrs: {{ $attrs }}</p>
    <p>pchild3Name: {{ $attrs.pchild3.name }}</p>
    <hr/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      child2:'child2'
    };
  },
  props: {
    pChild2:{
      type:String,
    }
  },
  inheritAttrs: false,
  mounted() {
    this.$emit("method2",this.child2);
  },
};
</script>

效果

總結(jié) 

到此這篇關(guān)于Vue中$attrs和$listeners詳解及使用的文章就介紹到這了,更多相關(guān)Vue $attrs、$listeners詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論