本篇博客咱们从上篇博客结束的mount部分延续分析,浅析从mount到页面的首次显示,主线和侧重点和只分析mount那篇博客不尽相同。
步骤分析
打开mount函数,可以看到调用了render,找到render首次声明的地方,进入patch函数中。
进入patch函数,可以看到执行了类型的对比,此时传入的类型应该为组件类型,故需要执行processComponent函数,进入该函数后,执行mountComponent函数,如下图:
下一步执行mountComponent中的setupComponent函数,进入其中,发现从虚拟DOM中拿出了属性和children,判断是否为一个状态的组件,判断完进行属性和插槽的初始化。 之后执行setupStatefulComponent,对当前组件进行一次代理,调用setup选项,如下图:
此时处理的是对象,所以使用handleSetupResult处理setup的结果,进行proxyRefs的包装,将数据变成响应式,如下图:
之后执行finishComponentSetup,该方法会进行一下判断,如果当前组件没有渲染函数,就为其生成一个渲染函数,同时也实现了兼容vue2的applyOptions(instance)方法,如下图: 分析完finishComponentSetup方法,我们返回到setupComponent所在位置,此时组件的实例化已经完成了。下一步执行setupRenderEffect函数,如下图:
执行其中的componentUpdateFn函数,该函数执行完就可以看到页面了,在effect创建更新机制,实例化了响应式副作用,传入组件更新函数当参数1,按照方式2的方式去执行方式1,如下图: 此时effect只是创建出来一个更新机制,并没有执行,这行代码将effect中的run函数拿出来放到实例的update函数里,用变量update将其储存起来,最后执行update,用户看到页面,代码如下图:
学习心得
沿主线探索某个功能的实现,有很多包之间是相互依赖的,到某个函数位置卡住的话,可以去寻找其依赖包功能的实现,理清楚逻辑之后再返回来,继续沿着功能实现的主线往下走。