前情回顾
在上一节中,我们可以看到instance.render()执行后的结果中,有些节点的值为undefined
因为他们引用的是instance身上的setup里的data
分析病情
那么归根结底就是instance.render()在执行的时候,instance身上没有对应的msg,data等属性,所以this.msg, this.data结果才会是undefined。
可是我们在对instance进行setupStateful的时候,已经把setup函数的执行结果,挂载到instance的setupState属性身上了呀,那么通过拿到instance.setupState属性是否就可以拿到我们想要的值了呢
答案是当然可以啦,但是怎么做到每次访问instance就可以拿到对应属性的返回值呢,总不可能把一个个属性写死吧?
解决办法
这时候就可以用到proxy代理对象啦,对instance.proxy做一层封装,每次访问的时候,返回setupSate里对应的属性值。
function setupStatefulComponent(instance) {
// 这里的component为什么等于instance.type??=> createVnode的时候只传递了第一个参数
const component = instance.type;
const { setup } = component;
if (setup) {
const setupResult = setup();
// setupResult可能是function 也可能是object
// 如果是function, 那么将它作为组件的render函数
// 如果是object,那么将它注入到组件的上下文中
handleSetupResult(instance, setupResult);
}
//添加监听
instance.proxy = new Proxy({}, {
get(target, key) {
const { setupState } = instance;
console.log('get函数里---', setupState);
if (key in setupState) {
return setupState[key];
}
},
});
}
添加一层proxy之后的instance
然后在处理subTree的地方,我们执行instance.render的时候,需要修改一下this指向,
// 原来的
function setupRenderEffect(instance, container) {
const subTree = instance.render()// 调用render函数生成组件的children的VNode
patch(subTree, container)
}
// 现在的
function setupRenderEffect(instance, container) {
const { proxy } = instance
const subTree = instance.render.call(proxy)// 调用render函数生成组件的children的VNode
patch(subTree, container)
}
解决this之前
解决this之后
可以看到subTree里的children的文本节点有值啦!