Vue3 组件通信学习笔记
一、父子組件之間通信
父子組件之間如何進(jìn)行通信呢?
- 父組件傳遞給子組件:通過props屬性;
- 子組件傳遞給父組件:通過$emit觸發(fā)事件;
1.1 父組件傳遞給子組件
在開發(fā)中很常見的就是父子組件之間通信,比如父組件有一些數(shù)據(jù),需要子組件來進(jìn)行展示:
- 這個時候我們可以通過props來完成組件之間的通信;
什么是Props呢? - Props是你可以在組件上注冊一些自定義的attribute;
- 父組件給這些attribute賦值,子組件通過attribute的名稱獲取到對應(yīng)的值;
Props有兩種常見的用法:
- 方式一:字符串?dāng)?shù)組,數(shù)組中的字符串就是attribute的名稱;
- 方式二:對象類型,對象類型我們可以在指定attribute名稱的同時,指定它需要傳遞的類型、是否是必須的、默認(rèn)值等等;
1.1.1 Props的數(shù)組用法
1.1.2 Props的對象用法
數(shù)組用法中我們只能說明傳入的attribute的名稱,并不能對其進(jìn)行任何形式的限制,接下來我們來看一下對象的寫法是如何讓我們的props變得更加完善的。
當(dāng)使用對象語法的時候,我們可以對傳入的內(nèi)容限制更多:
- 比如指定傳入的attribute的類型;
- 比如指定傳入的attribute是否是必傳的;
- 比如指定沒有傳入時,attribute的默認(rèn)值;
1.1.2.1 細(xì)節(jié)一:那么type的類型都可以是哪些呢?
那么type的類型都可以是哪些呢? pString
1.1.2.2 細(xì)節(jié)二:對象類型的其他寫法
1.1.2.4 細(xì)節(jié)三:Prop 的大小寫命名
Prop 的大小寫命名(camelCase vs kebab-case)
- HTML 中的 attribute 名是大小寫不敏感的,所以瀏覽器會把所有大寫字符解釋為小寫字符;
- 這意味著當(dāng)你使用 DOM 中的模板時,camelCase (駝峰命名法) 的 prop 名需要使用其等價的 kebab-case (短橫線分隔命名) 命名;
- 但是在vue-cli創(chuàng)建的項目中既可以使用 (短橫線分隔命名) ,也可使用(駝峰命名法) ,因為vue-cli是基于webpack構(gòu)建的,項目中文件后綴名為.vue的文件中的template標(biāo)簽中的內(nèi)容,都是通過vue-loader來進(jìn)行解析后再交給瀏覽器的,而不是直接交給瀏覽器來解析。
1.1.2.5 非Prop的Attribute
什么是非Prop的Attribute呢? 當(dāng)我們傳遞給一個組件某個屬性,但是該屬性并沒有定義對應(yīng)的props或者emits時,就稱之為非Prop的Attribute;
常見的包括class、style、id屬性等;
Attribute繼承
當(dāng)組件有單個根節(jié)點(diǎn)時,非Prop的Attribute將自動添加到根節(jié)點(diǎn)的Attribute中:
1.1.2.6 禁用Attribute繼承和多根節(jié)點(diǎn)
如果我們不希望組件的根元素繼承attribute,可以在組件中設(shè)置 inheritAttrs: false:
- 禁用attribute繼承的常見情況是需要將attribute應(yīng)用于根元素之外的其他元素;
- 我們可以通過 $attrs來訪問所有的 非props的attribute;
多個根節(jié)點(diǎn)的attribute - 多個根節(jié)點(diǎn)的attribute如果沒有顯示的綁定,那么會報警告:
在這里插入圖片描述
我們必須手動的指定要綁定到哪一個屬性上:
1.2 子組件傳遞給父組件
什么情況下子組件需要傳遞內(nèi)容到父組件呢?
- 當(dāng)子組件有一些事件發(fā)生的時候,比如在組件中發(fā)生了點(diǎn)擊,父組件需要切換內(nèi)容;
- 子組件有一些內(nèi)容想要傳遞給父組件的時候;
我們?nèi)绾瓮瓿缮厦娴牟僮髂?#xff1f;
- 首先,我們需要在子組件中定義好在某些情況下觸發(fā)的事件名稱;
- 其次,在父組件中以v-on的方式傳入要監(jiān)聽的事件名稱,并且綁定到對應(yīng)的方法中;
- 最后,在子組件中發(fā)生某個事件的時候,根據(jù)事件名稱觸發(fā)對應(yīng)的事件;
1.2.1 我們封裝一個CounterOperation.vue的組件
內(nèi)部其實是監(jiān)聽兩個按鈕的點(diǎn)擊,點(diǎn)擊之后通過 this.$emit的方式發(fā)出去事件;
1.2.2 自定義事件的參數(shù)和驗證
自定義事件的時候,我們也可以傳遞一些參數(shù)給父組件:
在vue3當(dāng)中,我們可以對傳遞的參數(shù)進(jìn)行驗證:
二、非父子組件通信
這里我們主要講兩種方式:
- Provide/Inject;
- Mitt全局事件總線;
2.1 Provide和Inject
Provide/Inject用于非父子組件之間共享數(shù)據(jù):
- 比如有一些深度嵌套的組件,子組件想要獲取父組件的部分內(nèi)容;
- 在這種情況下,如果我們?nèi)匀粚rops沿著組件鏈逐級傳遞下去,就會非常的麻煩;
對于這種情況下,我們可以使用 Provide 和 Inject :
- 無論層級結(jié)構(gòu)有多深,父組件都可以作為其所有子組件的依賴提供者;
- 父組件有一個 provide 選項來提供數(shù)據(jù);
- 子組件有一個 inject 選項來開始使用這些數(shù)據(jù);
實際上,你可以將依賴注入看作是“l(fā)ong range props”,除了:
- 父組件不需要知道哪些子組件使用它 provide 的 property
- 子組件不需要知道 inject 的 property 來自哪里
2.2 Provide和Inject基本使用
我們開發(fā)一個這樣的結(jié)構(gòu):
2.3 Provide和Inject函數(shù)的寫法
如果Provide中提供的一些數(shù)據(jù)是來自data,那么我們可能會想要通過this來獲取:
這個時候會報錯:
- 這里給大家留一個思考題,我們的this使用的是哪里的this?
答案:這里的this取的是script標(biāo)簽中的this, 值為undefined
2.4 處理響應(yīng)式數(shù)據(jù)
我們先來驗證一個結(jié)果:如果我們修改了this.names的內(nèi)容,那么使用length的子組件會不會是響應(yīng)式的?
我們會發(fā)現(xiàn)對應(yīng)的子組件中是沒有反應(yīng)的:
- 這是因為當(dāng)我們修改了names之后,之前在provide中引入的 this.names.length 本身并不是響應(yīng)式的;
那么怎么樣可以讓我們的數(shù)據(jù)變成響應(yīng)式的呢?
- 非常的簡單,我們可以使用響應(yīng)式的一些API來完成這些功能,比如說computed函數(shù);
- 當(dāng)然,這個computed是vue3的新特性
注意:我們在使用length的時候需要獲取其中的value
- 這是因為computed返回的是一個ref對象,需要取出其中的value來使用;
2.5 全局事件總線mitt庫
Vue3從實例中移除了 $on、$off 和 $once 方法,所以我們?nèi)绻M^續(xù)使用全局事件總線,要通過第三方的庫:
- Vue3官方有推薦一些庫,例如 mitt 或 tiny-emitter;
- 這里我們主要講解一下mitt庫的使用;
首先,我們需要先安裝這個庫:
npm install mitt其次,我們可以封裝一個工具eventbus.js:
2.6 使用事件總線工具
在項目中可以使用它們:
- 我們在About.vue中觸發(fā)事件;
- 我們在HomeContent.vue中監(jiān)聽事件;
2.7 Mitt的事件取消
在某些情況下我們可能希望取消掉之前注冊的函數(shù)監(jiān)聽:
總結(jié)
以上是生活随笔為你收集整理的Vue3 组件通信学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跳一跳python源码下载_python
- 下一篇: Vuex4学习笔记