Vue创建app及App挂载和渲染
1.执行createApp执行ensureRenderer去判断是否有渲染器,首次进入是没有渲染器的。所以会调用createRenderer函数创建渲染器创建渲染器的时候最终会返回一个对象,包括render、hydrate、createAppa. hydrate做服务端渲染b. render函数c. createApp会调用createAppAPI函数createAppAPI函数的调用,会返回cr
·
1.执行createApp
- 执行ensureRenderer去判断是否有渲染器,首次进入是没有渲染器的。所以会调用createRenderer函数创建渲染器
- 创建渲染器的时候最终会返回一个对象,包括render、hydrate、createApp
a. hydrate做服务端渲染
b. render函数
c. createApp会调用createAppAPI函数 - createAppAPI函数的调用,会返回createApp函数
- createApp函数返回一个包括App全局API的对象,包括use、mixins、component、directive、mount、unmount、provide
2.创建和渲染App的Vnode
- 在调用mount函数时,我们先将createApp的mount函数进行保存,如何进行重写,目的是为了能够跨平台。
a. 重写的normalizeContainer方法就是在web端获取我们的元素,依据我们的选择器。创建container。
b.先清空原有的container中的内容,如何调用保存的mount函数(与平台无关的代码)。 - mount函数内部首先使用createVNode创建vnode对象
- 调用render函数把vnode传进去渲染vnode
- 在render函数中判断vnode是否为null,如果是null则调用unmount函数卸载组件,否则调用patch函数挂载组件
- patch函数依据vnode的新老节点不同情况进行不同处理
a.如果新的节点和旧的节点类型不同, 那么会销毁整个子节点树
b.处理文本节点:processText
c.处理注释节点:processCommentNode
d.处理静态节点:mountStaticNode、patchStaticNode
e.处理Fragment组件节点:processFragment
f.处理普通的DOM元素:processElement
g.处理组件节点:processComponent
3.挂载App
- 第一次挂载根组件调用processComponent,由于此时没有老节点所以会调用mountComponent进行组件的挂载
- mountComponent调用createComponentInstance创建组件实例
- 再调用setupComponent函数对组件实例的数据进行初始化。
- 并且调用setupRenderEffect设置有副作用的函数(相当于依赖的收集)
a.在此函数中创建响应式的副作用渲染函数,effect。
b.effect的作用是当组件的数据发生变化时, effect函数包裹的内部函数componentEffect会重新执行一遍, 重新渲染组件
c.在effect中会判断组件实例是否已经挂载,如果已挂载,则进行组件的更新,会调用patch函数。
d.未挂载:
1.调用renderComponentRoot渲染组件,生成子树的vnode
2.使用patch函数把子树的vnode挂载到container中
3.将组件挂载状态改为已挂载
- patch函数,组件内部是普通节点时processElement调用mountElement(挂载节点)patchElement(更新节点)。以下说明挂载节点
a.从vnode中读出属性
b.根据属性创建DOM元素节点
c.如果子节点是数组则会调用mountChildren来处理子节点的children
d.处理好其他属性
e.将最后的el挂载到container上。
题目:
1.组件的VNode和组件的instance有什么区别?
Vnode:虚拟节点
instance:保存组件各种状态 data/setup/computed/methods...
2.为啥vue3会有多个根
vue3在外面包裹了一个Fragment
3.组件初始化setupComponent(instance)过程
处理props、attrs
处理slots
执行setup:const rst =setup() instance.setupSate = proxyRefs(rst)
编译template——> compile : <template> ——> render函数
对vue2的options api进行支持
4.对于template的编译,优化点
1.对于不会改变的静态节点,vue会在编译阶段进行作用域提升,先使用createVNode生成之后再加入到render中
vue是组件级的更新,这样我们在更新的使用调用render则不需要再创建静态节点,减少了性能的消耗。
2.非静态节点保存到一个数组中,在patch阶段的时候只对非静态节点进行diff。
render函数中会调用_openBlock函数,此函数会讲动态节点添加到dynamicChildren数组中(BlockTree的概念)
更多推荐
已为社区贡献3条内容
所有评论(0)