您好,登錄后才能下訂單哦!
這篇文章主要介紹了vue中provide / inject的作用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
Vue具體輕量級框架、簡單易學、雙向數據綁定、組件化、數據和結構的分離、虛擬DOM、運行速度快等優勢,Vue中頁面使用的是局部刷新,不用每次跳轉頁面都要請求所有數據和dom,可以大大提升訪問速度和用戶體驗。
1.前言
vue的父子組件通信用什么?
:prop和$emit的組合。
如果是爺孫組件呢?
:那么就要用父組件來轉發數據和事件了。
如果是太爺爺和孫子組件呢?
:當然是vuex啦
emmm 好的,沒我啥事了,我這就走。
不行,我還能再掙扎一會兒!肯定有一部分兄弟做的項目比較小,組件通信的情況不是很多,懶得引入vuex,那么provide/inject就是爺孫(不限于爺孫/父子,中間隔了多少級都可以)通信問題的最好解決方案啦!
2.官方文檔抄過來的介紹
這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效。
provide 選項應該是
一個對象或返回一個對象的函數。該對象包含可注入其子孫的屬性。在該對象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環境下可工作。
inject 選項應該是:
一個字符串數組,或
一個對象(詳情點擊 這里 )
3.基本用法
// 祖先組件 提供foo //第一種 export default { name: "grandfather", provide(){ return{ foo:'halo' } }, } //第二種 export default { name: "grandfather", provide:{ foo:'halo~~~~' }, } //后代組件 注入foo export default { inject:['foo'], }
上面的兩種用法有什么區別嗎?
如果你只是傳一個字符串,像上面的‘halo',那么是沒有區別的,后代都能讀到。
如果你需要傳一個對象(如下所示代碼),那么第二種是傳不了的,后代組件拿不到數據。所以建議只寫第一種
//當你傳遞對象給后代時 provide(){ return{ test:this.msg } },
注意: 一旦注入了某個數據,比如上面示例中的 foo,那這個組件中就不能再聲明 foo 這個數據了,因為它已經被父級占有。
4.什么時候才是可響應的?
如果你使用過vuex,那么你會認為,上面的例子中,如果我把 foo:'halo' 改成 foo:'world' ,子組件會及時響應數據變更,視圖完成更新。
可惜,沒有
在vue官方文檔中有這么一句話
提示: provide 和 inject 綁定并不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的對象,那么其對象的屬性還是可響應的。
這里不探討vue為什么要這么設計,我這里只展示啥時候provide/inject可響應
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) },
如上所示,這樣做是不行的,打印出來的 provided 中的數據并沒有改,子組件取得值也沒變。
你甚至可以直接給 this._provided.msg 賦值,但是 即使 是 _provided.msg 里面的值改變了,子組件的取值,依然沒有變。
當你像下面這樣做的時候,就可以響應了
provide(){ return{ test:this.activeData } }, data() { return { activeData:{name:'halo'}, } } mounted(){ setTimeout(()=>{ this.activeData.name = 'world'; },3000) }
這就是vue中寫道的 對象的屬性 是可以響應的
然而,如果你傳入了一個可監聽的對象,那么其對象的屬性還是可響應的。
5.實現全局變量
全局變量?provide/inject不是只能從祖先傳遞給后代嗎?沒錯,我們只要綁定到最最頂層的組件即可。
就是你啦! app.vue
我們把一整個實例都扔給后代!
//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();//可以執行app中的方法,變身為全局方法! } }
這個也是可響應的噢~
6.實現頁面刷新
1 . 用vue-router重新路由到當前頁面,頁面是不進行刷新的
2 . 采用window.reload(),或者router.go(0)刷新時,整個瀏覽器進行了重新加載,閃爍,體驗不好
那我們怎么做呢?
跟上面的原理差不多,我們只在控制路由的組件中寫一個函數(使用 v-if 控制 router-view 的顯示隱藏,這里的原理不作贅述),然后把這個函數傳遞給后代,然后在后代組件中調用這個方法即可刷新路由啦。
//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.結尾
vue中有這樣的提示
注意: provide 和 inject 主要為高階插件/組件庫提供用例。并不推薦直接用于應用程序代碼中。
provide/inject平時用的比較少,多數用于開發組件,但某些情況下還是很好用的。
業務龐大而復雜的,還是建議使用 vuex ~
感謝你能夠認真閱讀完這篇文章,希望小編分享的“vue中provide / inject的作用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。