Vue2.4 $attrs问慎、$listeners、inheritAttrs的使用

在開始介紹之前先看下vue官方文檔對 $attrs$listeners的解釋:

vm.$attrs
包含了父作用域中不作為 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)挤茄。當一個組件沒有聲明任何 prop 時如叼,這里會包含所有父作用域的綁定 (class 和 style 除外),并且可以通過 v-bind="$attrs" 傳入內部組件——在創(chuàng)建高級別的組件時非常有用穷劈。
vm.$listeners
包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器笼恰。它可以通過 v-on="$listeners" 傳入內部組件——在創(chuàng)建更高層次的組件時非常有用。

講真歇终,我看了幾遍也是沒看懂社证,既然如此那就舉個栗子來說明吧,先看如下圖組件多級嵌套的情況:

圖1

如圖所示评凝,A B C組件的嵌套關系如圖所示追葡,如果從數(shù)據從A組件到B組件則用props屬性即可,將更新的數(shù)據傳回A組件則采用$emit觸發(fā)A組件自定義函數(shù)即可奕短,那么直接從A組件到C組件如何傳遞數(shù)據呢宜肉?
方案1:采用Vuex進行統(tǒng)一的狀態(tài)管理。如果項目不是很大翎碑,組件間的全局共享狀態(tài)不多谬返,則使用vuex反而復雜
方案2:將A組件的數(shù)據傳到B組件在從B組件傳到C組件。會造成代碼繁瑣維護困難等日杈。
在vue2.4中遣铝,為了解決該需求佑刷,引入了$attrs$listeners , 新增了inheritAttrs 選項翰蠢。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <App />
        </div>
        <script src="../node_modules/vue/dist/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let GrandSon = {
                template: `<div>這是孫組件项乒,獲取的父組件信息為:{{coo}} {{ceo}}
                    <button type="button" @click="changeData">點擊更新數(shù)據到父組件</button>
                    <button type="button" @click="changeChildData">點擊更新數(shù)據到Child組件</button>
                    </div>`,
                props: ['coo','ceo'],//即使props中加入foo也無法獲取值啰劲,因為foo屬性已在Child組件注冊
                data(){
                    return {
                        
                    }
                },
                methods: {
                    changeData(){
                        this.$emit('updateData', {
                            name: 'zhang',
                            age: '22'
                        })
                    },
                    changeChildData(){
                        this.$emit('updateChildData', {
                            name: 'qianfeng'
                        })
                    }
                },
            }
            let Child = {
                props: ['foo'],
                inheritAttrs: true,
                template:`<div>這是子組件,獲取的父組件信息為:{{foo}}
                    <GrandSon  v-bind="$attrs" v-on="$listeners" @updateChildData="updateChildData" />
                </div>`,
                components: {
                    GrandSon,
                },
                mounted(){
                    //$attrs屬性獲取子組件的props中未注冊父組件傳遞過來的屬性梁沧,即除了foo以外的屬性
                    console.log('this.$attrs:', this.$attrs)
                },
                methods: {
                    updateChildData(data){
                        console.log(data)
                    }
                }
            }
            let App = {
                template: '<div>這是父組件<Child :foo="foo" :coo="coo" :ceo="ceo" @updateData="updateData" /></div>',
                data(){
                    return {
                        foo: '父組件內容foo',
                        coo: '父組件內容coo',
                        ceo: '父組件內容ceo',
                    }
                },
                components: {
                    Child,
                },
                methods: {
                    updateData(data){
                        console.log(data)
                    },
                },
            }
            let vm = new Vue({
                el: '#app',
                data(){
                    return {}
                },
                components: {
                    App,
                },
            })
        </script>
    </body>
</html>

如上述代碼,App代表A組件蝇裤,Child代表B組件廷支,GeandSon代表C組件,數(shù)據從A組件到B組件依然通過父組件自定義屬性栓辜,子組件注冊props接受屬性值的形式恋拍。
不同的是在Child組件中綁定了$attrs$listeners,而在Child組件props中注冊了父組件傳遞過來的foo屬性,在GrandSon組件的props中注冊了coo藕甩、ceo屬性施敢,那么$attrs則起到將coo ceo屬性從父組件傳到孫組件的作用,同樣如果要在孫組件改變數(shù)據后回傳到父組件狭莱,只需要在Child組件中綁定$listeners即可僵娃,依然是通過父組件自定義事件,孫組件通過$emit觸發(fā)函數(shù)腋妙。

接下來介紹inheritAttrs:

inheritAttrs:默認情況下父作用域的不被認作 props 的特性綁定 (attribute bindings) 將會“回退”且作為普通的 HTML 特性應用在子組件的根元素上默怨。當撰寫包裹一個目標元素或另一個組件的組件時,這可能不會總是符合預期行為骤素。通過設置 inheritAttrs 到 false匙睹,這些默認行為將會被去掉。而通過 (同樣是 2.4 新增的) 實例屬性 $attrs 可以讓這些特性生效济竹,且可以通過 v-bind 顯性的綁定到非根元素上痕檬。

執(zhí)行上面代碼查看子組件的DOM元素,如下圖:

image.png

簡單來說就是送浊,當子組件的props中未注冊父組件傳遞過來的屬性時:
當設置inheritAttrs: true(默認)時梦谜,子組件頂層標簽會渲染出父組件傳遞過來的屬性,
當設置inheritAttrs: true時罕袋,子組件頂層標簽不會渲染父組件傳遞過來的屬性改淑;
無論inheritAttrs為true或者false,子組件中都能通過$attrs屬性獲取到父組件中傳遞過來的屬性,參考上面的console.log(this. $attrs)打印出來的值即可浴讯。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末朵夏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子榆纽,更是在濱河造成了極大的恐慌仰猖,老刑警劉巖捏肢,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饥侵,居然都是意外死亡鸵赫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門躏升,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辩棒,“玉大人,你說我怎么就攤上這事膨疏∫徽觯” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵佃却,是天一觀的道長者吁。 經常有香客問我,道長饲帅,這世上最難降的妖魔是什么复凳? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮灶泵,結果婚禮上育八,老公的妹妹穿的比我還像新娘。我一直安慰自己丘逸,他們只是感情好单鹿,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著深纲,像睡著了一般仲锄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上湃鹊,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天儒喊,我揣著相機與錄音,去河邊找鬼币呵。 笑死怀愧,一個胖子當著我的面吹牛,可吹牛的內容都是我干的余赢。 我是一名探鬼主播芯义,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼妻柒!你這毒婦竟也來了扛拨?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤举塔,失蹤者是張志新(化名)和其女友劉穎绑警,沒想到半個月后求泰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡计盒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年渴频,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片北启。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡卜朗,死狀恐怖,靈堂內的尸體忽然破棺而出暖庄,到底是詐尸還是另有隱情聊替,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布培廓,位于F島的核電站,受9級特大地震影響春叫,放射性物質發(fā)生泄漏肩钠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一暂殖、第九天 我趴在偏房一處隱蔽的房頂上張望价匠。 院中可真熱鬧,春花似錦呛每、人聲如沸踩窖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洋腮。三九已至,卻和暖如春手形,著一層夾襖步出監(jiān)牢的瞬間啥供,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工库糠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伙狐,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓瞬欧,卻偏偏與公主長得像贷屎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子艘虎,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容