Vue中$attrs和$listeners詳解以及使用方法
- 傳送門(mén):Vue中 子組件向父組件傳值 及 .sync 修飾符 詳解
- 傳送門(mén):Vue中 狀態(tài)管理器(vuex)詳解及應(yīng)用場(chǎng)景
- 傳送門(mén):Vue中 事件總線(eventBus)詳解及使用
- 傳送門(mén):Vue中 provide、inject 詳解及使用
Vue中 常見(jiàn)的組件通信方式可分為三類(lèi)
父子通信
父向子傳遞數(shù)據(jù)是通過(guò) props,子向父是通過(guò) events($emit);
通過(guò)父鏈 / 子鏈也可以通信($parent / $children);
ref 也可以訪問(wèn)組件實(shí)例;
provide / inject;
$attrs/$listeners;
兄弟通信
Bus;
Vuex;
跨級(jí)通信
Bus;
Vuex;
provide / inject、
$attrs / $listeners、
1. 前言
多級(jí)組件嵌套需要傳遞數(shù)據(jù)時(shí),通常使用的方法是通過(guò) 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 和 事件總線 的情況下變得簡(jiǎn)潔,業(yè)務(wù)清晰。
首先分析以下應(yīng)用場(chǎng)景
A 組件與 B 組件之間的通信: (父子組件)
如上圖所示,A、B、C三個(gè)組件依次嵌套,按照 Vue 的開(kāi)發(fā)習(xí)慣,父子組件通信可以通過(guò)以下方式實(shí)現(xiàn):
- A to B 通過(guò) props 的方式向子組件傳遞,B to A 通過(guò)在 B 組件中 $emit, A 組件中 v-on 的方式實(shí)現(xiàn);
- 通過(guò)設(shè)置全局 Vuex 共享狀態(tài),通過(guò) computed 計(jì)算屬性和 commit mutation 的方式實(shí)現(xiàn)數(shù)據(jù)的獲取和更新,以達(dá)到父子組件通信的目的;
- Vue Event Bus,使用 Vue 的實(shí)例,實(shí)現(xiàn)事件的監(jiān)聽(tīng)和發(fā)布,實(shí)現(xiàn)組件之間的傳遞;
往往數(shù)據(jù)在不需要全局的情況而僅僅是父子組件通信時(shí),使用第一種方式即可滿足。
A 組件與 C 組件之間的通信: (跨多級(jí)的組件嵌套關(guān)系)
如上圖,A 組件與 C 組件之間屬于跨多級(jí)的組件嵌套關(guān)系,以往兩者之間如需實(shí)現(xiàn)通信,往往通過(guò)以下方式實(shí)現(xiàn):
- 借助 B 組件的中轉(zhuǎn),從上到下 props 依次傳遞,從下至上 $emit 事件的傳遞,達(dá)到跨級(jí)組件通信的效果;
- 借助 Vuex 的全局狀態(tài)共享;
- Vue Event Bus,使用 Vue 的實(shí)例實(shí)現(xiàn)事件的監(jiān)聽(tīng)和發(fā)布,實(shí)現(xiàn)組件之間的傳遞
第一種通過(guò) props 和 $emit 的方式,使得組件之間的業(yè)務(wù)邏輯臃腫不堪,B組件在其中僅僅充當(dāng)?shù)氖且粋€(gè)中轉(zhuǎn)站的作用;
第二種 Vuex 的方式,某些情況下似乎又有點(diǎn)大材小用的意味(僅僅是想實(shí)現(xiàn)組件之間的一個(gè)數(shù)據(jù)傳遞,并非數(shù)據(jù)共享的概念);
第三種情況的使用在實(shí)際的項(xiàng)目操作中發(fā)現(xiàn),如不能實(shí)現(xiàn)很好的事件監(jiān)聽(tīng)與發(fā)布的管理,往往容易導(dǎo)致數(shù)據(jù)流的混亂,在多人協(xié)作的項(xiàng)目中,不利于項(xiàng)目的維護(hù);
$attrs 以及 $listeners 的出現(xiàn)解決的就是第一種情況的問(wèn)題,B 組件在其中傳遞 props 以及事件的過(guò)程中,不必在寫(xiě)多余的代碼,
僅僅是將 $attrs 以及 $listeners 向上或者向下傳遞即可。
2. 知識(shí)點(diǎn)
inheritAttrs:默認(rèn)值 true,繼承所有的父組件屬性(除 props 的特定綁定)作為普通的HTML特性應(yīng)用在子組件的根元素上,如果你不希望組件的根元素繼承特性設(shè)置 inheritAttrs: false ,但是 class 屬性會(huì)繼承。
(簡(jiǎn)單的說(shuō),inheritAttrs:true 繼承除 props 之外的所有屬性;inheritAttrs:false 只繼承 class style 屬性)
$attrs–繼承所有的父組件屬性(除了 prop 傳遞的屬性、class 和 style ),一般用在子組件的子元素上
$ listeners屬性,它是一個(gè)對(duì)象,里面包含了作用在這個(gè)組件上的所有監(jiān)聽(tīng)器,你就可以配合 v-on="$listeners" 將所有的事件監(jiān)聽(tīng)器指向這個(gè)組件的某個(gè)特定的子元素。(相當(dāng)于子組件繼承父組件的事件)
3. 示例
A組件(App.vue)
<template> <div id="app"> <!-- 此處監(jiān)聽(tīng)了兩個(gè)事件,可以在B組件或者C組件中直接觸發(fā) --> <child1 :pchild1="child1" :pchild2="child2" :pchild3="child3" @method1="onMethod1" @method2="onMethod2"></child1> </div> </template> <script> import Child1 from "./Child1.vue"; export default { data() { return { child1:'1', child2: 2, child3:{ name:'child3' } }; }, components: { Child1 }, methods: { onMethod1(msg1) { console.log(`${msg1} running`); }, onMethod2(msg2) { console.log(`${msg2} running`); }, }, }; </script>
B組件(Child1.vue)
<template> <div class="child-1"> <h2>in child1</h2> <p>props: {{ pchild1 }}</p> <p>$attrs: {{ $attrs }}</p> <hr/> <!-- 通過(guò) v-bind 綁定$attrs屬性,C組件可以直接獲取到A組件中傳遞下來(lái)的props(除了B組件中props聲明的) --> <!-- C組件中能直接觸發(fā)test的原因在于 B組件調(diào)用C組件時(shí) 使用 v-on 綁定了$listeners 屬性 --> <child2 v-bind="$attrs" v-on="$listeners"></child2> </div> </template> <script> import Child2 from "./Child2.vue"; export default { data() { return { child1:'child1' }; }, components: { Child2 }, props: { pchild1:{ type:String } }, inheritAttrs: false, mounted() { this.$emit("method1",this.child1); }, }; </script>
C 組件 (Child2.vue)
<template> <div class="child-2"> <h2>in child2:</h2> <p>props: {{ pChild2 }}</p> <p>$attrs: {{ $attrs }}</p> <p>pchild3Name: {{ $attrs.pchild3.name }}</p> <hr/> </div> </template> <script> export default { data() { return { child2:'child2' }; }, props: { pChild2:{ type:String, } }, inheritAttrs: false, mounted() { this.$emit("method2",this.child2); }, }; </script>
效果
總結(jié)
到此這篇關(guān)于Vue中$attrs和$listeners詳解及使用的文章就介紹到這了,更多相關(guān)Vue $attrs、$listeners詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中v-model指令與.sync修飾符的區(qū)別詳解
本文主要介紹了vue中v-model指令與.sync修飾符的區(qū)別詳解,詳細(xì)的介紹了兩個(gè)的用法和區(qū)別,感興趣的可以了解一下2021-08-08vue-devtools 打開(kāi)源碼位置實(shí)現(xiàn)過(guò)程
這篇文章主要為大家介紹了vue-devtools 打開(kāi)源碼位置實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09vue在html標(biāo)簽{{}}中調(diào)用函數(shù)的方法總結(jié)及對(duì)比
這篇文章主要給大家介紹了關(guān)于vue在html標(biāo)簽{{}}中調(diào)用函數(shù)的方法總結(jié)及對(duì)比,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-03-03vue shallowRef作用及引發(fā)問(wèn)題詳解
這篇文章主要為大家介紹了vue shallowRef作用及引發(fā)問(wèn)題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08vue項(xiàng)目使用typescript創(chuàng)建抽象類(lèi)及其使用方式
這篇文章主要介紹了vue項(xiàng)目使用typescript創(chuàng)建抽象類(lèi)及其使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Vite中使用Ant?Design?Vue3.x框架教程示例
這篇文章主要為大家介紹了Vite中使用Ant?Design?Vue3.x框架教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06vue項(xiàng)目依賴升級(jí)報(bào)錯(cuò)處理方式
這篇文章主要介紹了vue項(xiàng)目依賴升級(jí)報(bào)錯(cuò)處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08