sailei1 / blog

1 stars 0 forks source link

vue 组件更新理解 #38

Closed sailei1 closed 5 years ago

sailei1 commented 5 years ago

image

首次渲染 记录vnode 为以后进行对比

新旧节点不同时 1 找到旧节点的父节点(组件初始节点), 创建新节点,挂载在父节点上 2 更新父的占位符节点 更新组件dom 3 删除旧的vnode节点。

父组件的值 改变时 如果是子组件的prop的key, 子组件执行 prepatch-> updateChildComponent 然后 子组件的prop key 会重新赋值,触发子组件 prop key setter 然后子组件更新。

新旧节点相同时

先执行 prepatch updateChildComponent

拿新旧节点的children

1 判断text类型 节点 普通文本节点 直接更新文本

2 不是text类型 1 新旧节点 children都存在 执行updateChildren 2 只有新节点 有children 的情况下 老节点清空 把新节点批量插入 3 只有老的节点 有children, 把老节点删除 4 新旧节点都没有children 表明是文本节点,清除节点内容

updateChildren 操作解析

记录 旧节点开始位置 新节点开始位置 旧节点结束位置 新节点结束位置

判断 旧节点开始位置 是不是还存在 不存在 index++ 旧节点结束位置是不是还存在 不存在 index--

在索引值 index 1 判断 开始索引值 新旧节点 是否相等 2 判断 新旧节点最后一个 是否相等 3 判断旧节点开始节点 然后跟 新节点最后一个 是否相等 4 判断旧节点末尾节点 跟新节点开始值 是否相等 5 新旧key 是否相等 找到key标记的元素 对比是否没操作 然后复用跟新增

新旧 索引值移动 不断缩小对比范围

满足 oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx 条件 不断对比新旧节点 然后 递归执行 patchvnode()

循环完以后 记录 旧节点开始位置 新节点开始位置 旧节点结束位置 新节点结束位置 如果旧节点开始位置大于旧节点结束位置 添加新节点 如果新节点开始位置大于新节点结束位置 移除节点

sailei1 commented 5 years ago

页面上显示的 收集key 触发getter, 修改时 触发setter 更新vnode, 然后对比vnode 触发组件更新,从而进行dom 更新