淺析vue中的provide / inject 有什么用處
1.前言
vue的父子組件通信用什么?
:prop和$emit的組合。
如果是爺孫組件呢?
:那么就要用父組件來(lái)轉(zhuǎn)發(fā)數(shù)據(jù)和事件了。
如果是太爺爺和孫子組件呢?
:當(dāng)然是vuex啦
emmm 好的,沒(méi)我啥事了,我這就走。
不行,我還能再掙扎一會(huì)兒!肯定有一部分兄弟做的項(xiàng)目比較小,組件通信的情況不是很多,懶得引入vuex,那么provide/inject就是爺孫(不限于爺孫/父子,中間隔了多少級(jí)都可以)通信問(wèn)題的最好解決方案啦!
2.官方文檔抄過(guò)來(lái)的介紹
這對(duì)選項(xiàng)需要一起使用,以允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴(lài),不論組件層次有多深,并在起上下游關(guān)系成立的時(shí)間里始終生效。
provide 選項(xiàng)應(yīng)該是
- 一個(gè)對(duì)象或返回一個(gè)對(duì)象的函數(shù)。該對(duì)象包含可注入其子孫的屬性。在該對(duì)象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環(huán)境下可工作。
inject 選項(xiàng)應(yīng)該是:
- 一個(gè)字符串?dāng)?shù)組,或
- 一個(gè)對(duì)象(詳情點(diǎn)擊 這里 )
3.基本用法
// 祖先組件 提供foo //第一種 export default { name: "grandfather", provide(){ return{ foo:'halo' } }, } //第二種 export default { name: "grandfather", provide:{ foo:'halo~~~~' }, } //后代組件 注入foo export default { inject:['foo'], }
上面的兩種用法有什么區(qū)別嗎?
- 如果你只是傳一個(gè)字符串,像上面的‘halo',那么是沒(méi)有區(qū)別的,后代都能讀到。
- 如果你需要傳一個(gè)對(duì)象(如下所示代碼),那么第二種是傳不了的,后代組件拿不到數(shù)據(jù)。所以建議只寫(xiě)第一種
//當(dāng)你傳遞對(duì)象給后代時(shí) provide(){ return{ test:this.msg } },
注意: 一旦注入了某個(gè)數(shù)據(jù),比如上面示例中的 foo,那這個(gè)組件中就不能再聲明 foo 這個(gè)數(shù)據(jù)了,因?yàn)樗呀?jīng)被父級(jí)占有。
4.什么時(shí)候才是可響應(yīng)的?
如果你使用過(guò)vuex,那么你會(huì)認(rèn)為,上面的例子中,如果我把 foo:'halo' 改成 foo:'world' ,子組件會(huì)及時(shí)響應(yīng)數(shù)據(jù)變更,視圖完成更新。
可惜,沒(méi)有
在vue官方文檔中有這么一句話(huà)
提示: provide 和 inject 綁定并不是可響應(yīng)的。這是刻意為之的。然而,如果你傳入了一個(gè)可監(jiān)聽(tīng)的對(duì)象,那么其對(duì)象的屬性還是可響應(yīng)的。
這里不探討vue為什么要這么設(shè)計(jì),我這里只展示啥時(shí)候provide/inject可響應(yīng)
provide(){ return{ test:this.msg } }, data() { return { msg: "Welcome to Your Vue.js App", } } mounted(){ setTimeout(()=>{ this.msg = "halo world"; console.log(this._provided.msg) //log:Welcome to Your Vue.js App },3000) },
如上所示,這樣做是不行的,打印出來(lái)的 provided 中的數(shù)據(jù)并沒(méi)有改,子組件取得值也沒(méi)變。
你甚至可以直接給 this._provided.msg 賦值,但是 即使 是 _provided.msg 里面的值改變了,子組件的取值,依然沒(méi)有變。
當(dāng)你像下面這樣做的時(shí)候,就可以響應(yīng)了
provide(){ return{ test:this.activeData } }, data() { return { activeData:{name:'halo'}, } } mounted(){ setTimeout(()=>{ this.activeData.name = 'world'; },3000) }
這就是vue中寫(xiě)道的 對(duì)象的屬性 是可以響應(yīng)的
然而,如果你傳入了一個(gè)可監(jiān)聽(tīng)的對(duì)象,那么其對(duì)象的屬性還是可響應(yīng)的。
5.實(shí)現(xiàn)全局變量
全局變量?provide/inject不是只能從祖先傳遞給后代嗎?沒(méi)錯(cuò),我們只要綁定到最最頂層的組件即可。
就是你啦! app.vue
我們把一整個(gè)實(shí)例都扔給后代!
//app.vue export default { name: 'App', provide(){ return{ app:this } }, data(){ return{ text:"it's hard to tell the night time from the day" } }, methods:{ say(){ console.log("Desperado, why don't you come to your senses?") } } } //其他所有子組件,需要全局變量的,只需要按需注入app即可 export default { inject:['foo','app'], mounted(){ console.log(this.app.text);//獲取app中的變量 this.app.say();//可以執(zhí)行app中的方法,變身為全局方法! } }
這個(gè)也是可響應(yīng)的噢~
6.實(shí)現(xiàn)頁(yè)面刷新
1 . 用vue-router重新路由到當(dāng)前頁(yè)面,頁(yè)面是不進(jìn)行刷新的
2 . 采用window.reload(),或者router.go(0)刷新時(shí),整個(gè)瀏覽器進(jìn)行了重新加載,閃爍,體驗(yàn)不好
那我們?cè)趺醋瞿兀?/p>
跟上面的原理差不多,我們只在控制路由的組件中寫(xiě)一個(gè)函數(shù)(使用 v-if 控制 router-view 的顯示隱藏,這里的原理不作贅述),然后把這個(gè)函數(shù)傳遞給后代,然后在后代組件中調(diào)用這個(gè)方法即可刷新路由啦。
//app.vue <router-view v-if="isShowRouter"/> export default { name: 'App', provide(){ return{ reload:this.reload } }, data(){ return{ isShowRouter:true, } }, methods:{ reload(){ this.isShowRouter = false; this.$nextTick(()=>{ this.isShowRouter = true; }) } } } //后代組件 export default { inject:['reload'], }
7.結(jié)尾
vue中有這樣的提示
注意: provide 和 inject 主要為高階插件/組件庫(kù)提供用例。并不推薦直接用于應(yīng)用程序代碼中。
provide/inject平時(shí)用的比較少,多數(shù)用于開(kāi)發(fā)組件,但某些情況下還是很好用的。
業(yè)務(wù)龐大而復(fù)雜的,還是建議使用 vuex ~
總結(jié)
以上所述是小編給大家介紹的vue中的provide / inject 有什么用處,希望對(duì)大家有所幫助!
- vue中的provide/inject的學(xué)習(xí)使用
- vue3中?provide?和?inject?用法及原理
- vue 解決provide和inject響應(yīng)的問(wèn)題
- 解析vue的provide和inject使用方法及其原理
- 聊聊Vue中provide/inject的應(yīng)用詳解
- vue2實(shí)現(xiàn)provide inject傳遞響應(yīng)式
- Vue 2.0 中依賴(lài)注入 provide/inject組合實(shí)戰(zhàn)
- vue中provide?inject的響應(yīng)式監(jiān)聽(tīng)解決方案
- vue2.0/3.0中provide和inject的用法示例
- vue2和vue3中provide/inject的基本用法示例
相關(guān)文章
vue?+elementui?項(xiàng)目登錄通過(guò)不同賬號(hào)切換側(cè)邊欄菜單的顏色
這篇文章主要介紹了vue?+elementui?項(xiàng)目登錄通過(guò)不同賬號(hào)切換側(cè)邊欄菜單的顏色,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01vue.js頁(yè)面加載執(zhí)行created,mounted的先后順序說(shuō)明
這篇文章主要介紹了vue.js頁(yè)面加載執(zhí)行created,mounted的先后順序說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Vant picker 多級(jí)聯(lián)動(dòng)操作
這篇文章主要介紹了Vant picker 多級(jí)聯(lián)動(dòng)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11vue3中的reactive函數(shù)聲明數(shù)組方式
這篇文章主要介紹了vue3中的reactive函數(shù)聲明數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05Vue純前端實(shí)現(xiàn)導(dǎo)出Excel并修改樣式
這篇文章主要為大家詳細(xì)介紹了Vue如何利用xlsx-style庫(kù)實(shí)現(xiàn)導(dǎo)出Excel并修改樣式的功能,文中的示例代碼講解詳細(xì),有需要的可以參考下2024-01-01