$attrs、$listeners在Vue中的使用

在多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí),通常會(huì)想到的方法是使用vuex或者bus傳值,又或者事件觸發(fā)傳值,但是如果僅僅是傳遞一下數(shù)據(jù),而不做中間的處理,用這幾種方法感覺并不是特別的理想。所以就有了 attrs /listeners ,通常配合 inheritAttrs 一起使用。

inheritAttrs:默認(rèn)值為 true。
默認(rèn)情況下父作用域的不被認(rèn)作 props 的 attribute 綁定 (attribute bindings) 將會(huì)“回退”且作為普通的 HTML attribute 應(yīng)用在子組件的根元素上。當(dāng)撰寫包裹一個(gè)目標(biāo)元素或另一個(gè)組件的組件時(shí),這可能不會(huì)總是符合預(yù)期行為。通過設(shè)置 inheritAttrsfalse,這些默認(rèn)行為將會(huì)被去掉。而通過 (同樣是 2.4 新增的) 實(shí)例 property $attrs 可以讓這些 attribute 生效,且可以通過 v-bind 顯性的綁定到非根元素上。查 看 官 網(wǎng)

感覺還是挺晦澀難懂的,簡單的說就是 inheritAttrs:true 繼承除props之外的所有屬性;inheritAttrs:false 只繼承class屬性

attrs:包含了父作用域中不被認(rèn)為 (且不預(yù)期為) props 的特性綁定 (class 和 style 除外),并且可以通過 v-bind=”attrs” 傳入內(nèi)部組件。當(dāng)一個(gè)組件沒有聲明任何 props 時(shí),它包含所有父作用域的綁定 (class 和 style 除外)。

listeners:包含了父作用域中的 (不含 .native 修飾符) v-on 事件監(jiān)聽器。它可以通過 v-on=”listeners” 傳入內(nèi)部組件。它是一個(gè)對象,里面包含了作用在這個(gè)組件上的所有事件監(jiān)聽器,相當(dāng)于子組件繼承了父組件的事件。

話不多說,咱先上栗子
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, 因?yàn)楦附M件共傳來name, infoObj2個(gè)值,由于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é):這種方式的傳值對我來說不常用,感覺可讀性不是很好。但當(dāng)你在構(gòu)建一個(gè)多層嵌套的組件時(shí),對于組件層級(jí)嵌套比較深,使用props會(huì)很繁瑣,或者項(xiàng)目比較小,不太適合使用 Vuex 的時(shí)候,可以考慮用它。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容