在多級組件嵌套需要傳遞數(shù)據(jù)時蛮寂,通常會想到的方法是使用vuex或者bus傳值,又或者事件觸發(fā)傳值易茬,但是如果僅僅是傳遞一下數(shù)據(jù)酬蹋,而不做中間的處理,用這幾種方法感覺并不是特別的理想抽莱。所以就有了 listeners 范抓,通常配合 inheritAttrs 一起使用。
inheritAttrs:默認值為 true食铐。
默認情況下父作用域的不被認作 props 的 attribute 綁定 (attribute bindings) 將會“回退”且作為普通的 HTML attribute 應用在子組件的根元素上匕垫。當撰寫包裹一個目標元素或另一個組件的組件時,這可能不會總是符合預期行為虐呻。通過設置inheritAttrs
到false
象泵,這些默認行為將會被去掉。而通過 (同樣是 2.4 新增的) 實例 property$attrs
可以讓這些 attribute 生效斟叼,且可以通過v-bind
顯性的綁定到非根元素上偶惠。查 看 官 網(wǎng)
感覺還是挺晦澀難懂的,簡單的說就是 inheritAttrs:true 繼承除props之外的所有屬性朗涩;inheritAttrs:false 只繼承class屬性
attrs” 傳入內(nèi)部組件。當一個組件沒有聲明任何 props 時谢床,它包含所有父作用域的綁定 (class 和 style 除外)扒腕。
listeners” 傳入內(nèi)部組件萤悴。它是一個對象瘾腰,里面包含了作用在這個組件上的所有事件監(jiān)聽器,相當于子組件繼承了父組件的事件覆履。
話不多說蹋盆,咱先上栗子
father.vue組件
<template>
<child :name="name" :infoObj="infoObj" @updateInfo="updateInfo" />
</template>
<script>
import Child from '../components/child.vue'
export default {
name: 'father',
components: { Child },
data () {
return {
name: 'Lily',
infoObj: {
from: '上海',
}
}
},
methods: {
updateInfo() {
console.log('update info');
}
}
}
</script>
child.vue 組件:
<template>
<grand-son :height="height" @addInfo="addInfo" v-bind="$attrs" v-on="$listeners" />
// 通過 $listeners 將父作用域中的事件,傳入 grandSon 組件硝全,使其可以獲取到 father 中的事件
</template>
<script>
import GrandSon from '../components/grandSon.vue'
export default {
name: 'child',
components: { GrandSon },
props: ['name'],
data() {
return {
height: '180cm',
weight: '70kg'
};
},
created() {
console.log(this.$attrs);
// 結(jié)果:infoObj, 因為父組件共傳來name, infoObj2個值栖雾,由于name被 props接收了,所以只有infoObj屬性
console.log(this.$listeners); // updateInfo: f
},
methods: {
addInfo () {
console.log('add info')
}
}
}
</script>
grandSon.vue 組件:
<template>
<div>
{{ $attrs }} --- {{ $listeners }}
<div>
</template>
<script>
export default {
... ...
created() {
console.log(this.$attrs); // infoObj, height
console.log(this.$listeners) // updateInfo: f, addInfo: f
this.$emit('updateInfo') // 可以觸發(fā) father 組件中的updateInfo函數(shù)
}
}
</script>
總結(jié):這種方式的傳值對我來說不常用伟众,感覺可讀性不是很好析藕。但當你在構(gòu)建一個多層嵌套的組件時,對于組件層級嵌套比較深凳厢,使用props會很繁瑣账胧,或者項目比較小竞慢,不太適合使用 Vuex 的時候,可以考慮用它治泥。