vue2.x,vue3.x使用provide/inject注入的區(qū)別說(shuō)明
vue2.x,vue3.x使用provide/inject注入?yún)^(qū)別
provide/inject介紹
provide/inject通信方式屬于爺孫通信,vue2.x與vue3.x區(qū)別還是很大,無(wú)論層級(jí)多深,發(fā)起provide的組件都可以作為其所有下級(jí)組件的依賴(lài)提供者。
inject在data/props之前初始化,而provide在data/props之后初始化。目的是讓用戶(hù)可以在data/props中使用inject所注入的內(nèi)容。也就是說(shuō),為了data/props依賴(lài)inject,需要將初始化inject放在初始化data/props的前面。
provide和inject綁定并不是可響應(yīng)的,這是刻意為之,但是若傳入了一個(gè)可響應(yīng)的對(duì)象,那么其對(duì)象的 property 還是可響應(yīng)的。**
vue2.x用法
vue2,x中provide用法和data 類(lèi)似,都是配置為一個(gè)返回對(duì)象的函數(shù),
export default (){ data:( ? ? return { ? ? ?msg:"messgae" ? ? ?} ? ), provide:(? ? ? return { ? ? ? ? msg:this.msg ? ? ?} ? ) ? }
export default { ? inject: [ 'msg'], ? mounted () { ? ? console.log(this.msg); ? } }
vue3.x用法
inject()只能放在setup()生命周期里運(yùn)行,不能放在別的周期里運(yùn)行,也不能放在事件周期里運(yùn)行(也就是不能放在異步函數(shù)中,當(dāng)執(zhí)行到inject時(shí),此時(shí)已經(jīng)不在setup生命周期中)。
另外在setup中不能使用this,因?yàn)閟etup實(shí)在data、computed、methods之前執(zhí)行的,所以this是取不到組件中的變量的。
- setTimeout、promise.then()、鼠標(biāo)事件的回掉等都不可在函數(shù)里面執(zhí)行inject
- provide 和 inject 并不是可響應(yīng)的,但是由于引用類(lèi)型的特殊性,在子孫組件拿到了數(shù)據(jù)之后,他們的屬性還是可以正常的響應(yīng)變化。引用類(lèi)型的數(shù)據(jù),拿到后可以直接用,屬性的值更新后,子孫組件也會(huì)被更新。由于不具備真正的響應(yīng)性,給模板使用依然不會(huì)更新視圖。
- 基本數(shù)據(jù)類(lèi)型被直接 provide 出去后,再怎么修改,都無(wú)法更新下去,子孫組件拿到的永遠(yuǎn)是第一次的那個(gè)值。
<script setup> import { provide } from "vue" provide("msg","zhangsan") </script>
<script setup> import { inject } from "vue" let msg = inject('msg') conslole.log(msg) </script>
問(wèn)題:是否一定要定義成響應(yīng)式數(shù)據(jù)或者引用類(lèi)型數(shù)據(jù),孫子組件才能實(shí)時(shí)接收到爺爺組件數(shù)據(jù)的最新值(不談視圖更新,只論是否可以接收到到更新)?
可以定義基本數(shù)據(jù)類(lèi)型,但是要將其return 出去。如下所示:
let name = "zhangsan" provide('msg',()=>{ ? ?return 'name' })
const message = inject("msg") console.log(message()) //zhsngan
基本數(shù)據(jù)類(lèi)型,需要 provide 一個(gè)函數(shù),將其 return 出去給子孫組件用,這樣子孫組件每次拿到的數(shù)據(jù)才會(huì)是新的。但由于不具備響應(yīng)性,所以子孫組件每次都需要重新通過(guò)執(zhí)行 inject 得到的函數(shù)才能拿到最新的數(shù)據(jù)。
禁止孫子組件修改爺爺組件值
可使用shallowRef、readonly包裹需要傳遞的參數(shù)
shallowRef
:只處理基本數(shù)據(jù)類(lèi)型的響應(yīng)式, 不進(jìn)行對(duì)象的響應(yīng)式處理。readonly
:接收一個(gè) ref 或者 reactive 包裝對(duì)象,返回一個(gè)只讀的響應(yīng)式對(duì)象。
?const user = ref('張三') ?provide('user', readonly(user)) // readonly是為了防止inject端修改數(shù)據(jù)影響到provide端
vue的依賴(lài)注入問(wèn)題
當(dāng)一個(gè)module擁有超過(guò)兩層的組件時(shí),從后代組件一層層emit出去調(diào)用祖先組件的方法或一層層將祖先的數(shù)據(jù)用props傳遞到后代組件實(shí)在是太麻煩,當(dāng)需要修改時(shí)也需要一層層去找需要修改的地方
vue.js提供了一個(gè)“依賴(lài)注入”的方式,在這個(gè)方式中用到了兩個(gè)新的實(shí)例選項(xiàng):provide和inject
provide選項(xiàng)允許我們指定我們想要提供給后代組件的數(shù)據(jù)/方法。
祖先組件:
... data() { ?return { ? msg: ‘I am origin component data' ?} }, provide: function() { ?return { ? getData() { ? ?console.log(‘hi,I come from origin component') ? } ?}, ?msg: this.msg }, ...
inject可以在任何后代組件使用來(lái)接受我們?cè)谧嫦戎付ǖ臄?shù)據(jù)/方法
后代組件:
... inject: [‘getData', ‘msg'], created() { ?this.init() }, methods: { ?init() { ? console.log(this.msg), ? this.getData() ?} } ...
然而,依賴(lài)注入還是有負(fù)面影響的。它將你應(yīng)用程序中的組件與它們當(dāng)前的組織方式耦合起來(lái),使重構(gòu)變得更加困難。
同時(shí)所提供的 property 是非響應(yīng)式的。這是出于設(shè)計(jì)的考慮,因?yàn)槭褂盟鼈儊?lái)創(chuàng)建一個(gè)中心化規(guī)?;臄?shù)據(jù)跟使用 $root做這件事都是不夠好的。
如果你想要共享的這個(gè) property 是你的應(yīng)用特有的,而不是通用化的,或者如果你想在祖先組件中更新所提供的數(shù)據(jù),那么這意味著你可能需要換用一個(gè)像 Vuex 這樣真正的狀態(tài)管理方案了
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用iView Upload 組件實(shí)現(xiàn)手動(dòng)上傳圖片的示例代碼
這篇文章主要介紹了使用iView Upload 組件實(shí)現(xiàn)手動(dòng)上傳圖片的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Vue結(jié)合路由配置遞歸實(shí)現(xiàn)菜單欄功能
這篇文章主要介紹了Vue結(jié)合路由配置遞歸實(shí)現(xiàn)菜單欄,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)火鍋工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法分析
這篇文章主要介紹了Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法,總的來(lái)說(shuō)這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過(guò)程。希望通過(guò)這道題能給你帶來(lái)一種解題優(yōu)化的思路2022-11-11vue 不使用select實(shí)現(xiàn)下拉框功能(推薦)
這篇文章主要介紹了vue 不使用select實(shí)現(xiàn)下拉框功能,在文章給大家提到了vue select 組件的使用與禁用,需要的朋友可以參考下2018-05-05Vue項(xiàng)目中quill-editor帶樣式編輯器的使用方法
這篇文章主要介紹了Vue項(xiàng)目中quill-editor帶樣式編輯器的使用方法,可以更改插入圖片和視頻,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08使用Vue?Query實(shí)現(xiàn)高級(jí)數(shù)據(jù)獲取的示例詳解
構(gòu)建現(xiàn)代大規(guī)模應(yīng)用程序最具挑戰(zhàn)性的方面之一是數(shù)據(jù)獲取,這也是?Vue?Query?庫(kù)的用途所在,下面就跟隨小編一起學(xué)習(xí)一下如何利用Vue?Query實(shí)現(xiàn)高級(jí)數(shù)據(jù)獲取吧2023-08-08vue和thymeleaf相結(jié)合的注意事項(xiàng)詳解
這篇文章主要介紹了vue和thymeleaf相結(jié)合的注意事項(xiàng)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Ant?Design_Form表單上傳文件組件實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Ant?Design_Form表單上傳文件組件實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03