【vue3 原理】组件代理对象

168 阅读1分钟

前言

上一篇最后提到:

我们打算在根组件render中使用this.msg获取setup状态,但显然还没有实现这部分逻辑,看不到效果,只有undefinedthis是什么?它是怎么获取状态的?

接下来我们实现这一部分

render 中的 this

runtime-core/renderer.js

function setupRenderEffect(instance, container){
+	const { proxy } = instance

+	const subTree = instance.render.call(proxy)

	patch(subTree, container)
}

我们在调用 render时将this指定为组件实例上的Proxy对象1

指定为Proxy对象而不是组件实例的原因是我们调用 setup返回的结果是保存在组件实例setupState属性上,我们不想在获取状态时还需要this.setupState.msg的方式,而是通过this.msg更简洁的方式获取

下面我们实现这个Proxy对象

Proxy 对象

runtime-core/component.js

export function setupStatefulComponent(instance){
	const { setup,render } = instance.vnode.type
	const setupResult = setup()	
	instance.setupState = setupResult

+	instance.proxy = new Proxy(
+		{},
+		{
+			get(target, key) {
+				const { setupState } = instance
+				if(key in setupState){
+					return setupState[key]
+				}
+			}
+		}
+	)

	instance.render = render
}

组件实例setupState中检查对应属性是否存在,存在则返回

总结

vue3 原理 - 组件代理对象.png

image.png

Footnotes

  1. Proxy