問(wèn)題:子孫組件如何共享數(shù)據(jù)
-
vue2.x
提供provide
選項(xiàng)
// Provider
export default {
provide: function () {
return {
foo: this.foo
}
}
}
// Consumer
export default {
inject: ['foo']
}
-
vue3.0
可以使用provide API
// Provider
import { provide, ref } from 'vue'
export default {
setup() {
const theme = ref('dark')
provide('theme', theme)
}
}
// Consumer
import { inject } from 'vue'
export default {
setup() {
const theme = inject('theme', 'light')
return {
theme
}
}
}
- 祖先組件不需要知道哪些后代組件在使用它提供的數(shù)據(jù)
- 后代組件也不需要知道注入的數(shù)據(jù)來(lái)自哪里
provide API 的實(shí)現(xiàn)原理
function provide(key, value) {
let provides = currentInstance.provides
const parentProvides = currentInstance.parent && currentInstance.parent.provides
if (parentProvides === provides) {
provides = currentInstance.provides = Object.create(parentProvides)
}
provides[key] = value
}
- 創(chuàng)建組件實(shí)例的時(shí)候锅棕,組件實(shí)例的 provides 對(duì)象指向父組件實(shí)例的 provides 對(duì)象
- 組件實(shí)例的 provides 繼承它的父組件
- 在
inject
階段挽荠,我們可以非常容易通過(guò)原型鏈查找來(lái)自直接父級(jí)提供的數(shù)據(jù) - 注意:
- 組件實(shí)例提供和父級(jí)
provides
中有相同key
的數(shù)據(jù),是可以覆蓋父級(jí)提供的數(shù)據(jù)
- 組件實(shí)例提供和父級(jí)
inject API實(shí)現(xiàn)原理
function inject(key, defaultValue) {
const instance = currentInstance || currentRenderingInstance
if (instance) {
const provides = instance.provides
if (key in provides) {
return provides[key]
}
else if (arguments.length > 1) {
return defaultValue
}
else if ((process.env.NODE_ENV !== 'production')) {
warn(`injection "${String(key)}" not found.`)
}
}
}
-
inject
支持兩個(gè)參數(shù)- 第一個(gè)參數(shù)是
key
:我們可以訪問(wèn)組件實(shí)例中的 provides 對(duì)象對(duì)應(yīng)的 key贫贝,層層查找父級(jí)提供的數(shù)據(jù) - 第二個(gè)參數(shù)是默認(rèn)值慢宗,如果查找不到數(shù)據(jù)虽抄,則直接返回默認(rèn)值
- 第一個(gè)參數(shù)是
provide/inject共享數(shù)據(jù)與export共享數(shù)據(jù)
作用域
- 依賴注入
- 它的作用域是局部范圍
- 不是這棵子樹(shù)上的組件是不能訪問(wèn)到該數(shù)據(jù)的
- 模塊化
- 作用域是全局范圍
- 可以在任何地方引用它導(dǎo)出的數(shù)據(jù)
數(shù)據(jù)來(lái)源
- 依賴注入
- 后代組件是不需要知道注入的數(shù)據(jù)來(lái)自哪里脸侥,只管注入并使用即可
- 模塊化
- 用戶必須明確知道這個(gè)數(shù)據(jù)是在哪個(gè)模塊定義的
上下文
- 依賴注入
- 提供數(shù)據(jù)的組件的上下文就是組件實(shí)例
- 同一個(gè)組件定義是可以有多個(gè)組件實(shí)例的畏纲,我們可以根據(jù)不同的組件上下文提供不同的數(shù)據(jù)給后代組件
- 模塊化
- 沒(méi)有任何上下文