Vue - 組件通信之$attrs哼勇、$listeners

前言

vue通信手段有很多種炸庞,props/emit、vuex翠勉、event bus妖啥、provide/inject 等。還有一種通信方式对碌,那就是 $attrs$listeners荆虱,這種方式很優(yōu)雅,使用起來也不賴朽们。下面例子都會(huì)通過父(index)怀读、子(child)、孫子(grandson)华坦,三者的關(guān)系來說明使用方式愿吹。

組件關(guān)系圖

$attrs

官方解釋:
包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定 (class 和 style 除外)。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí)惜姐,這里會(huì)包含所有父作用域的綁定 (class 和 style 除外)犁跪,并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件——在創(chuàng)建高級(jí)別的組件時(shí)非常有用椿息。

我的理解:
接收除了props聲明外的所有綁定屬性(class、style除外)

index.vue
    <child class="arrts"  id="10"   age="20"  sex="男" ></child>
   <!--在 子組件中展示 $arrts:{  "age": "20",  "sex": "男" } 坷衍;class和style 特殊的不會(huì)被綁定 -->
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兩個(gè)屬性枫耳,輸出結(jié)果為:
{ "age": "20", "sex": "男" }
$attrs 里面接收的是 除了porps里面定義屬性之外的值


  • child子組件可以通過 v-bind="$attrs" 定義到grandson.vue 上乏矾,把 index.vue 中定義的屬性傳遞到"孫組件"上。讓 grandson.vue 也能訪問到父組件的屬性迁杨,這在傳遞多個(gè)屬性時(shí)會(huì)顯得很便捷钻心,而不用一條條的進(jìn)行綁定。

  • 如果想要添加其他屬性铅协,可繼續(xù)綁定屬性捷沸。但要注意的是,繼續(xù)綁定的屬性和 $attrs 中的屬性有重復(fù)時(shí)狐史,繼續(xù)綁定的屬性優(yōu)先級(jí)會(huì)更高

child.vue -> grandson.vue

$listeners

如果$attrs 是操作父子傳參的痒给,那$listeners就是操作父組件傳遞子組件方法的

官方解釋:
包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定 (class 和 style 除外)。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí)骏全,這里會(huì)包含所有父作用域的綁定 (class 和 style 除外)苍柏,并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件——在創(chuàng)建高級(jí)別的組件時(shí)非常有用。

我的理解

  • $listeners$attrs 類似姜贡,只不過$attrs是v-bind 而 $listeners是用v-on 而已试吁,
  • 接收除了帶有.native事件修飾符的所有事件監(jiān)聽器
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'); 
  },
};
//打印結(jié)果: 因?yàn)樵趇ndex.vue中g(shù)etMessage有native修飾,所以不會(huì)觸發(fā)
// {getInfo: ?}getInfo: ? invoker()[[Prototype]]: Object '====listeners'
grandson.vue
<script>
export default {
  created() {
    console.log(this.$listeners, "====listeners");
  },
};
</script>

//打印結(jié)果:
// {getInfo: ?, getMessage: ?}getInfo: ? invoker()getMessage: ? invoker()[[Prototype]]: Object '====listeners'
$listeners 事件監(jiān)聽
  • attrs 屬性一樣鲁豪,可以通過v-on="$listeners"潘悼,將事件監(jiān)聽器繼續(xù)向下傳遞,讓 grandson.vue 訪問到事件爬橡,且可以使用 $emit 觸發(fā) parent.vue 的函數(shù)治唤。
  • 如果想要添加其他事件監(jiān)聽器,可繼續(xù)綁定事件糙申。但要注意的是宾添,繼續(xù)綁定的事件和 $listeners 中的事件有重復(fù)時(shí),不會(huì)被覆蓋柜裸。
    即: 當(dāng) grandson.vue 觸發(fā) getMessage 事件時(shí)缕陕,child.vue 和 parent.vue 的事件都會(huì)被觸發(fā),觸發(fā)順序類似于冒泡疙挺,先到 child.vue 再到 parent.vue扛邑。


    觸發(fā)冒泡事件

    解釋:當(dāng)index.vue 和child.vue 綁定相同的事件的時(shí)候,grandson.vue 會(huì)先觸發(fā)child的事件后觸發(fā)index.vue 的事件铐然,所以寫代碼時(shí)事件名稱不要重復(fù)蔬崩。

代碼地址:碼云 vue-question 組件通訊
參考文檔:Vue - 組件通信之a(chǎn)ttrs恶座、listeners

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沥阳,隨后出現(xiàn)的幾起案子跨琳,更是在濱河造成了極大的恐慌,老刑警劉巖桐罕,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脉让,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡功炮,警方通過查閱死者的電腦和手機(jī)溅潜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來死宣,“玉大人伟恶,你說我怎么就攤上這事∫愀茫” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵潦牛,是天一觀的道長(zhǎng)眶掌。 經(jīng)常有香客問我,道長(zhǎng)巴碗,這世上最難降的妖魔是什么朴爬? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮橡淆,結(jié)果婚禮上召噩,老公的妹妹穿的比我還像新娘。我一直安慰自己逸爵,他們只是感情好具滴,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著师倔,像睡著了一般构韵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趋艘,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天疲恢,我揣著相機(jī)與錄音,去河邊找鬼瓷胧。 笑死显拳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搓萧。 我是一名探鬼主播杂数,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼遇八,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了耍休?” 一聲冷哼從身側(cè)響起刃永,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎羊精,沒想到半個(gè)月后斯够,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喧锦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年读规,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片燃少。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡束亏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阵具,到底是詐尸還是另有隱情碍遍,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布阳液,位于F島的核電站怕敬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏帘皿。R本人自食惡果不足惜东跪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹰溜。 院中可真熱鬧虽填,春花似錦、人聲如沸曹动。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)仁期。三九已至桑驱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跛蛋,已是汗流浹背熬的。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赊级,地道東北人押框。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像理逊,于是被迫代替她去往敵國(guó)和親橡伞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盒揉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容