如果帮助到大佬,请给小弟一个赞哈!
provides的来源
每个组件在形成实例时:如果有父组件,则使用父组件的provides,没有则为{}
const instance = {
type: vnode.type,
vnode,
next: null,
props: {},
parent,
provides: parent ? parent.provides : {},
proxy: null,
isMounted: false,
attrs: {},
slots: {},
ctx: {},
setupState: {},
emit: () => { },
};
复制代码
provides源码
void 0同等于undefined,想知道为什么使用void 0,自行百度。通过上面代码已知实例如果有父组件,实例的provides等于parent.provides。
- 当parentProvides === provides,把当parentProvides放在provides的原型链中。如果某组件中访问key,会优先访问的父组件设置的key,找不到的话则继续向外找。
- provides[key] = value; 设置自己的provide。
function provide(key, value) {
var _a;
const currentInstance = getCurrentInstance();
if (currentInstance) {
let { provides } = currentInstance;
const parentProvides = (_a = currentInstance.parent) === null || _a === void 0 ? void 0 : _a.provides;
if (parentProvides === provides) {
provides = currentInstance.provides = Object.create(parentProvides);
}
provides[key] = value;
}
}
复制代码
上面的分析是否正确?我们验证一下,多层嵌套组件都设置了provide,然后打印最深的子组件的实例。
provides确实是觉有多层原型链,大家可以去验证一下。
inject源码
- 现在原型链上找key,使用in遍历,会遍历到原形链。找到则return provides[key]。
- 没有找到,但传人了defaultValue,defaultValue是函数则return执行结果,不是函数直接return defaultValue。
- 原型链没找到,也没有设置默认值,则会不会return,也就会默认return undefined。
function inject(key, defaultValue) {
var _a;
const currentInstance = getCurrentInstance();
if (currentInstance) {
const provides = (_a = currentInstance.parent) === null || _a === void 0 ? void 0 : _a.provides;
if (key in provides) {
return provides[key];
} else if (defaultValue) {
if (typeof defaultValue === "function") {
return defaultValue();
}
return defaultValue;
}
}
}
复制代码
总结
这部分源码是非常简单的,大家尽量去阅读一下。