$attrs, $listeners, inheritAttrs - 2018-06-15

  • 2018-06-15創(chuàng)建

組價(jià)通信

vue中一個(gè)比較令人煩惱的事情是屬性只能從父組件傳遞給子組件。這也就意味著當(dāng)你想向嵌套層級(jí)比較深組件數(shù)據(jù)傳遞我碟,只能由父組件傳遞給子組件,子組件再傳遞給孫子組件...

多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí)伶唯,通常使用的方法是通過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 和事件總線的情況下變得簡潔篮愉,業(yè)務(wù)清晰。

vm.$attrs

包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的特性綁定 (class 和 style 除外)差导。當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí)试躏,這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件

示例

<template>
  <div class="home">
    <mytest  :title="title" :massgae="massgae"></mytest>
  </div>
</template>
<script>
export default {
  name: 'home',
  data () {
    return {
      title:'title1111',
      massgae:'message111'
    }
  },
  components:{
    'mytest':{
      template:`<div>這是個(gè)h1標(biāo)題{{title}}</div>`,
      props:['title'],
      data(){
        return{
          mag:'111'
        }
      },
      created:function(){
        console.log(this.$attrs)//注意這里
      }
    }
  }
}
</script>

上邊的代碼设褐,我們?cè)诮M件里只是用了title這個(gè)屬性颠蕴,massgae屬性我么是沒有用的,那么下瀏覽器渲染出來是什么樣呢络断?如下圖:


image.png

我們看到:組件內(nèi)未被注冊(cè)的屬性將作為普通html元素屬性被渲染裁替,如果想讓屬性能夠向下傳遞,即使prop組件沒有被使用貌笨,你也需要在組件上注冊(cè)。這樣做會(huì)使組件預(yù)期功能變得模糊不清襟沮,同時(shí)也難以維護(hù)組件的DRY锥惋。在Vue2.4.0,可以在組件定義中添加inheritAttrs:false昌腰,組件將不會(huì)把未被注冊(cè)的props呈現(xiàn)為普通的HTML屬性。但是在組件里我們可以通過其$attrs可以獲取到?jīng)]有使用的注冊(cè)屬性膀跌,如果需要鸦泳,我們?cè)谶@也可以往下繼續(xù)傳遞日月。

components:{
    'mytest':{
      template:`<div>這是個(gè)h1標(biāo)題{{title}}</div>`,
      props:['title'],
      inheritAttrs: false,
      data(){
        return{
          mag:'111'
        }
      },
      created:function(){
        console.log(this.$attrs)//注意這里
      }
    }
image.png

繼續(xù)

$attrs

包含了父作用域中不被認(rèn)為 (且不預(yù)期為) props 的特性綁定 (class 和 style 除外)。當(dāng)一個(gè)組件沒有聲明任何 props 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外)肯腕,并且可以通過 v-bind=”$attrs” 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。

$listeners

包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器否纬。它可以通過 v-on=”$listeners” 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用盖袭。

inheritAttrs

默認(rèn)情況下父作用域的不被認(rèn)作 props 的特性綁定 (attribute bindings) 將會(huì)“回退”且作為普通的 HTML 特性應(yīng)用在子組件的根元素上。當(dāng)撰寫包裹一個(gè)目標(biāo)元素或另一個(gè)組件的組件時(shí)熄诡,這可能不會(huì)總是符合預(yù)期行為可很。通過設(shè)置 inheritAttrs 到 false,這些默認(rèn)行為將會(huì)被去掉凰浮。而通過 (同樣是 2.4 新增的) 實(shí)例屬性 $attrs 可以讓這些特性生效我抠,且可以通過 v-bind 顯性的綁定到非根元素上。
上述特性的使用完全可以降低在不使用Vuex以及事件總線的情況下袜茧,組件跨級(jí)props以及事件傳遞的復(fù)雜度菜拓。

完整示例

image.png

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

A組件(App.vue)

<template>
 <div id="app">
 <child1
 :p-child1="child1"
 :p-child2="child2"
 v-on:test1="onTest1" //此處監(jiān)聽了兩個(gè)事件递递,可以在B組件或者C組件中直接觸發(fā)
 v-on:test2="onTest2"> 
 </child1>
 </div>
</template>
<script>
 import Child1 from './Child1.vue';
 export default {
 data () {
 return {};
 },
 components: { Child1 },
 methods: {
 onTest1 () {
 console.log('test1 running...');
 },
 onTest2 () {
 console.log('test2 running');
 }
 }
 };
</script>

B組件(Child1.vue)

<template>
 <div class="child-1">
 <p>in child1:</p>
 <p>props: {{pChild1}}</p>
 <p>$attrs: {{$attrs}}</p>
 <hr>
 <!-- C組件中能直接觸發(fā)test的原因在于 B組件調(diào)用C組件時(shí) 使用 v-on 綁定了$listeners 屬性 -->
 <!-- 通過v-bind 綁定$attrs屬性喷橙,C組件可以直接獲取到A組件中傳遞下來的props(除了B組件中props聲明的) -->
 <child2 v-bind="$attrs" v-on="$listeners"></child2>
 </div>
</template>
<script>
 import Child2 from './Child2.vue';
 export default {
 props: ['pChild1'],
 data () {
 return {};
 },
 inheritAttrs: false,
 components: { Child2 },
 mounted () {
 this.$emit('test1');
 }
 };
</script>

結(jié)果:

in child1:

props: v_child1

$attrs: { “p-child2”: “v_child2”}

C 組件 (Child2.vue)

<template>
 <div class="child-2">
 <p>in child2:</p>
 <p>props: {{pChild2}}</p>
 <p>$attrs: {{$attrs}}</p>
 <hr>
 </div>
</template>
<script>
 export default {
 props: ['pChild2'],
 data () {
 return {};
 },
 inheritAttrs: false,
 mounted () {
 this.$emit('test2');
 }
 };
</script>

結(jié)果:

in child2:

props: v_child2

$attrs: {}

其他

<template>
 <component
    :is="type"
    v-bind="vbinds"
    @getValue="(v) => getValue(v, i)"
    />
</template>
<script>
 export default {
 
 data () {
 return {
   vbinds: {
      ismultiple: '',
      region: '',
      logic: ''
   }
 };
 },

 };
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市登舞,隨后出現(xiàn)的幾起案子贰逾,更是在濱河造成了極大的恐慌,老刑警劉巖菠秒,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疙剑,死亡現(xiàn)場離奇詭異,居然都是意外死亡践叠,警方通過查閱死者的電腦和手機(jī)言缤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來禁灼,“玉大人管挟,你說我怎么就攤上這事∨叮” “怎么了僻孝?”我有些...
    開封第一講書人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵导帝,是天一觀的道長。 經(jīng)常有香客問我穿铆,道長您单,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任荞雏,我火速辦了婚禮虐秦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凤优。我一直安慰自己悦陋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開白布别洪。 她就那樣靜靜地躺著叨恨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挖垛。 梳的紋絲不亂的頭發(fā)上痒钝,一...
    開封第一講書人閱讀 52,821評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音痢毒,去河邊找鬼送矩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哪替,可吹牛的內(nèi)容都是我干的栋荸。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼凭舶,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼晌块!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帅霜,我...
    開封第一講書人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤匆背,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后身冀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钝尸,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年搂根,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了珍促。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剩愧,死狀恐怖猪叙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤沐悦,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布成洗,位于F島的核電站五督,受9級(jí)特大地震影響藏否,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜充包,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一副签、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧基矮,春花似錦淆储、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钢悲,卻和暖如春点额,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背莺琳。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來泰國打工还棱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惭等。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓珍手,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辞做。 傳聞我的和親對(duì)象是個(gè)殘疾皇子琳要,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

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

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容秤茅。關(guān)于...
    云之外閱讀 5,052評(píng)論 0 29
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,222評(píng)論 0 6
  • 哈嘍嫂伞,我是樊登讀書會(huì)福建分會(huì)首席書童林麗花孔厉。 在這個(gè)快速變化的時(shí)代,方法比勤奮更重要帖努,我們?cè)僖膊幌襁^去那樣靠加班博...
    花麗林閱讀 425評(píng)論 1 0
  • 1撰豺、 畢業(yè)季前夕,國外某高中11年級(jí)拼余,召開了一次年級(jí)大會(huì)污桦,這次的演講視頻刷爆了朋友圈,被譽(yù)為是“今年最好的演講匙监,每...
    謝四毛閱讀 2,797評(píng)論 0 1
  • 在我的周圍凡橱,有很多人都離過婚小作。可是當(dāng)她們?cè)僖淮巫哌M(jìn)婚姻的時(shí)候稼钩,為什么在上一次婚姻中出現(xiàn)的問題還會(huì)重現(xiàn)顾稀,沒有吸取教訓(xùn)...
    解憂小店主閱讀 304評(píng)論 0 2