创建组件实例过程mountComponent,setup启动函数:
const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
// 创建组件实例,创建实例对象,绑上各种属性
const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense))
// 设置组件实例,初始化props/插槽、设置有状态的组件实例
setupComponent(instance)
// 设置并运行带副作用的渲染函数
setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized)
}
//设置组件实例--设置有状态的组件实例,
//1,PublicInstanceProxyHandlers函数设置代理,
//其中利用了缓存,缓存访问的属性的类型,0:setupState,1:data,2:props,3:ctx,且按照这个优先级访问属性
//对渲染上下文 instance.ctx 属性的访问和修改,代理到对 setupState、data、props、ctx 中的数据的访问和修改
//2,执行setup函数,
//如果setup有参数,创建setupContext,返回的对象{attrs,slots,emit},并且把[props, {attrs,slots,emit}]传入setup函数中
//3,处理setup的返回结果,如果是个函数,返回给instance.render,如果是个对象,包裹成reactive的对象赋值给setupState
function setupStatefulComponent (instance, isSSR) {
const Component = instance.type
// 创建渲染代理的属性访问缓存
instance.accessCache = {}
// 创建渲染上下文代理,设置了get和set拦截,get的时候按照优先级去取值,set的时候按照优先级去赋值,props不能赋值
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers)
// 判断处理 setup 函数
const { setup } = Component
if (setup) {
// 如果 setup 函数带参数,则创建一个 setupContext
const setupContext = (instance.setupContext =
setup.length > 1 ? createSetupContext(instance) : null)
// 执行 setup 函数,获取结果
const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [instance.props, setupContext])
// 处理 setup 执行结果
handleSetupResult(instance, setupResult)
}
else {
// 完成组件实例设置,标准化模板或者渲染函数和兼容 Options API
finishComponentSetup(instance)
}
}
//设置setup的context
function createSetupContext (instance) {
return {
attrs: instance.attrs,
slots: instance.slots,
emit: instance.emit
}
}
//处理setup的返回结果
function handleSetupResult(instance, setupResult) {
if (isFunction(setupResult)) {
// setup 返回渲染函数
instance.render = setupResult
}
else if (isObject(setupResult)) {
// 把 setup 返回结果变成响应式
instance.setupState = reactive(setupResult)
}
finishComponentSetup(instance)
}