# 前言
上一小节,我们介绍了数据访问代理的过程以及组件实例初始化的过程,接下来,我们将介绍组件的更新逻辑,这部分逻辑主要包含在 setupRenderEffect 这个函数中。
# 组件更新
const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
function componentUpdateFn() {
if (!instance.isMounted) {
// 初始化组件
}
else {
// 更新组件
}
}
// 创建响应式的副作用渲染函数
instance.update = effect(componentUpdateFn, prodEffectOptions)
}
@前端进阶之旅: 代码已经复制到剪贴板
在前面的小节中,我们说完了关于 mounted 的流程。接下来我们将着重来看一下组件更新的逻辑:
const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
function componentUpdateFn() {
if (!instance.isMounted) {
// 初始化组件
}
else {
// 更新组件
let { next, vnode } = instance
// 如果有 next 的话说明需要更新组件的数组(props, slot 等)
if (next) {
next.el = vnode.el
// 更新组件实例信息
updateComponentPreRender(instance, next, optimized)
} else {
next = vnode
}
// 获取新的子树 vnode
const nextTree = renderComponentRoot(instance)
// 获取旧的子树 vnode
const prevTree = instance.subTree
// 更新子树 vnode
instance.subTree = nextTree
// patch 新老子树的 vnode
patch(
prevTree,
nextTree,
// 处理 teleport 相关
hostParentNode(prevTree.el),
// 处理 fragment 相关
getNextHostNode(prevTree),
instance,
parentSuspense,
isSVG)
// 缓存更新后的 DOM 节点
next.el = nextTree.el
}
}
// 创建响应式的副作用渲染函数
instance.update = effect(componentUpdateFn, prodEffectOptions)
}
@前端进阶之旅: 代码已经复制到剪贴板
这里的核心流程是通过 next 来判断当前是否需要更新 vnode 的节点信息,然后渲染出新的子树 nextTree,再进行比对新旧子树并
