您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Vue2中Provide Inject依賴注入源碼分析”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
該步驟其實發(fā)生在 initState 之前,但是由于 provide/inject 一般是配合使用,所以這里調(diào)整了一下順序。
該函數(shù)的定義與過程都比較簡單:
export function initInjections(vm: Component) { const result = resolveInject(vm.$options.inject, vm) if (result) { toggleObserving(false) Object.keys(result).forEach(key => { if (__DEV__) { defineReactive(vm, key, result[key], () => warn('')) } else { defineReactive(vm, key, result[key]) } }) toggleObserving(true) } } export function resolveInject(inject: any, vm: Component): Record<string, any> | undefined | null { if (inject) { const result = Object.create(null) const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject) for (let i = 0; i < keys.length; i++) { const key = keys[i] if (key === '__ob__') continue const provideKey = inject[key].from if (provideKey in vm._provided) { result[key] = vm._provided[provideKey] } else if ('default' in inject[key]) { const provideDefault = inject[key].default result[key] = isFunction(provideDefault) ? provideDefault.call(vm) : provideDefault } else if (__DEV__) { warn('') } } return result } }
在 initInjections 函數(shù)中,只是遍歷了 options.inject 配置的依賴數(shù)據(jù),并 關(guān)閉 了依賴數(shù)據(jù)的 響應(yīng)式依賴收集,最后通過 defineReactive 將對應(yīng)的數(shù)據(jù)掛載到實例 vm 上,以便后面能直接訪問。
這就是官方提示的 為什么 provide/inject 的數(shù)據(jù)不是響應(yīng)式的了。
而 resolveInject 函數(shù)就是用來對組件的 inject 依賴數(shù)據(jù)進行處理,并返回一個沒有多余原型鏈的對象。
在官方文檔中,inject 接收一個字符串?dāng)?shù)組或者一個 key 為 string 的對象,而作為對象時則 必須 有 from 字段來表示依賴數(shù)據(jù)的獲取指向,另外也接收一個 default 屬性作為降級時使用的默認值。
但是,在 mergeOptions 之后,會將 options.inject 轉(zhuǎn)為標(biāo)準(zhǔn)對象格式。
并且這里并沒有對注入數(shù)據(jù) provide[key] 進行處理,而是直接賦值;所以才有:如果你傳入了一個可監(jiān)聽的對象,那么其對象的 property 還是可響應(yīng)的。
resolveInject() 函數(shù)就是解析標(biāo)準(zhǔn)格式 inject 配置,并將上層組件的 provide 的值或者 default 默認值綁定到函數(shù)返回對象中;如果這兩個都沒有,則會提示錯誤信息 “injection xx not found”
初始化注入數(shù)據(jù)的過程也很簡單,整個過程其實與 initInjection 類似。其函數(shù)定義如下:
export function initProvide(vm: Component) { const provideOption = vm.$options.provide if (provideOption) { const provided = isFunction(provideOption) ? provideOption.call(vm) : provideOption if (!isObject(provided)) { return } const source = resolveProvided(vm) const keys = hasSymbol ? Reflect.ownKeys(provided) : Object.keys(provided) for (let i = 0; i < keys.length; i++) { const key = keys[i] Object.defineProperty( source, key, Object.getOwnPropertyDescriptor(provided, key)! ) } } } export function resolveProvided(vm: Component): Record<string, any> { const existing = vm._provided const parentProvides = vm.$parent && vm.$parent._provided if (parentProvides === existing) { return (vm._provided = Object.create(parentProvides)) } else { return existing } }
官方文檔中對 provide 配置項的說明是,可以是一個對象或者一個返回對象的函數(shù)。
所以這里首先判斷了 options.provide 的類型并獲取到了結(jié)果,如果結(jié)果 不是對象則會直接退出。
然后,則是初始化 provide 的數(shù)據(jù)。
此時會將當(dāng)前實例的 provided 數(shù)據(jù)與父組件實例的 provided 進行比較,如果相同,則返回一個 以父組件實例 provided 數(shù)據(jù)為原型創(chuàng)建的對象,否則直接返回當(dāng)前實例的 provided 數(shù)據(jù)。
因為每一個實例都會進行與父組件實例的注入數(shù)據(jù)比較,所以才能多層級傳遞
最后,則是遍歷 provided 對象,通過 Object.defineProperty 來處理數(shù)據(jù)獲取。
“Vue2中Provide Inject依賴注入源碼分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。