您好,登錄后才能下訂單哦!
前言
Vue中父組件到子組件的通信主要由子組件的props屬性實(shí)現(xiàn)。但是在一些情況下,父組件無(wú)法直接向子組件的props傳值。比如子組件通過(guò)父組件的slot進(jìn)入父組件,父組件根本不知道子組件是誰(shuí),更不用說(shuō)用子組件的props了。這時(shí)應(yīng)該怎么辦呢?Vue在2.2.0版本引入了provide與inject,正好適合處理這一情況。
什么是provide與inject
用文檔的話說(shuō):
provide/inject需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在起上下游關(guān)系成立的時(shí)間里始終生效。如果你熟悉 React,這與 React 的上下文特性很相似。
這就是說(shuō)從父組件的provide屬性傳入一個(gè)對(duì)象,子組件(或者是孫組件,只要是子級(jí)組件)可以用inject屬性接收父組件的provide屬性。比如
// main.vue <template> <c1 message="hello world"> <c2></c2> </c1> </template> // c1.vue <template> <div id="c1"> <slot></slot> </div> </template> <script> export default { props: ['message'], provide () { return { message: this.message } } } </script> // c2.vue <template> <div id="c2"> {{ message }} </div> </template> <script> export default { inject: ['message'] } </script>
上面的main組件會(huì)被渲染為:
<div id="c1"> <div id= "c2">hello world</div> </div>
可以看到,c1組件在不清楚子組件是什么的情況下,將它的props中的message傳給了c2組件。在這里c1組件就像是一個(gè)數(shù)據(jù)源一樣,為子組件提供數(shù)據(jù)。但是,c1組件提供的數(shù)據(jù)僅在c1的子孫組件中可見(jiàn),因此可以算作是有作用域限定的數(shù)據(jù)源。
父到子孫組件方向的數(shù)據(jù)流
父到子孫組件方向是provide/inject機(jī)制設(shè)計(jì)時(shí)的數(shù)據(jù)流方向。我們可能會(huì)猜想,在父組件中更改provide的值,子組件會(huì)響應(yīng)式的發(fā)生改變。但是注意到文檔中話。
提示:provide和inject綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽(tīng)的對(duì)象,那么其對(duì)象的屬性還是可響應(yīng)的。
這意味著,如果provide的值不是可監(jiān)聽(tīng)對(duì)象時(shí),在父組件中更改provide的值,子組件不會(huì)發(fā)生任何變化。比如模板仍然為上面那個(gè)例子的模板,message的值是一個(gè)props屬性,不是可監(jiān)聽(tīng)對(duì)象,如果我們?cè)赾1的mounted鉤子函數(shù)里改變message的值。如:
// c1.vue <script> export default { //... mounted () { setTimeout( () => { this.message = 'Opps, it would not be rendered' }, 1000) } } </script>
子組件不會(huì)響應(yīng)修改后的值。
但是如果provide的值是一個(gè)可監(jiān)聽(tīng)對(duì)象呢?請(qǐng)看一下例子:
<script> // c1.vue export default { data () { return { message: 'hello world' } }, provide () { messageData: this.$data }, mounted () { setTimeout(() => { this.message = 'I can show in c2.' }, 10000) } } </script> // c2.vue <template> <div id="c2"> {{ messageData.message }} </div> </template> <script> export default { inject: ['messageData'] } </script>
此時(shí)在c1掛載10s后,子組件將會(huì)顯示I can show in c2。為什么呢?c2中messageData實(shí)際上就是c1實(shí)例的this.$data。而this.$data上有message的響應(yīng)式getter與setter。所以c2的視圖會(huì)被message的dep收集,因此在c1中更新message,c2的視圖也會(huì)更新。
縱觀整個(gè)過(guò)程,provide/inject機(jī)制是非響應(yīng)式的,即provide與inject之間沒(méi)有綁定。具體的值是在子組件初始化過(guò)程中決定的。
總結(jié)
provide/inject提供了一種新的組件間通信的方法。它允許父組件向子孫組件間進(jìn)行跨層級(jí)的數(shù)據(jù)分發(fā)。但是provide/inject是非響應(yīng)式的,如果要子孫組件根據(jù)父組件的值進(jìn)行改變,provide/inject機(jī)制不是一個(gè)好的選擇。此時(shí)可以使用Vuex來(lái)管理狀態(tài)。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。