很多人都在思考vue2和vue3有区别吗?使用方法变了吗?语法以及其他的区别相差大么?需要重新学习新的语法么?vue2和vue3的差别还是挺大的,提供了新的特性和功能。下面说一下部分的差异
vue2/react-diff算法
下面来看个diff图。清晰显示了DOM更新的流程
* 首先比较一下新旧节点是不是同一个节点(可通过比较sel(选择器)和key(唯一标识)值是不是相同),不是同一个节点则进行暴力删除。
* 若是同一个节点则需要进一步比较:完全相同,不做处理;新节点内容为文本,直接替换完事;新节点有子节点,这个时候就要仔细考虑一下了:若老节点没有子元素,则直接清空老节点,将新节点的子元素插入即可;若老节点有子元素则就需要按照上述的更新策略老搞定了。这是vue2/react的diff算法
vue3-diff算法(增加了静态标记:PatchFlag)
- vue3的diff算法进行进一步的优化,性能方面比vue2提升了1.2~2倍。
#### vue3 的 DOM Diff 部分核心算法
function getSequence(arr: number[]): number[] {
const p = arr.slice()
const result = [0]
let i, j, u, v, c
const len = arr.length
for (i = 0; i < len; i++) {
const arrI = arr[i]
if (arrI !== 0) {
j = result[result.length - 1]
if (arr[j] < arrI) {
p[i] = j
result.push(i)
continue
}
u = 0
v = result.length - 1
while (u < v) {
c = ((u + v) / 2) | 0
if (arr[result[c]] < arrI) {
u = c + 1
} else {
v = c
}
}
if (arrI < arr[result[u]]) {
if (u > 0) {
p[i] = result[u - 1]
}
result[u] = i
}
}
}
u = result.length
v = result[u - 1]
while (u-- > 0) {
result[u] = v
v = p[v]
}
return result
}
function getSequence(arr: number[]): number[] {
const p = arr.slice() // 拷贝一个数组 p
const result = [0]
let i, j, u, v, c
const len = arr.length
for (i = 0; i < len; i++) {
const arrI = arr[i]
// 排除等于 0 的情况
if (arrI !== 0) {
j = result[result.length - 1]
// 与最后一项进行比较
if (arr[j] < arrI) {
p[i] = j // 最后一项与 p 对应的索引进行对应
result.push(i)
continue
}
// arrI 比 arr[j] 小,使用二分查找找到后替换它
// 定义二分查找区间
u = 0
v = result.length - 1
// 开启二分查找
while (u < v) {
// 取整得到当前位置
c = ((u + v) / 2) | 0
if (arr[result[c]] < arrI) {
u = c + 1
} else {
v = c
}
}
// 比较 => 替换
if (arrI < arr[result[u]]) {
if (u > 0) {
p[i] = result[u - 1] // 正确的结果
}
result[u] = i // 有可能替换会导致结果不正确,需要一个新数组 p 记录正确的结果
}
}
}
u = result.length
v = result[u - 1]
// 倒叙回溯 用 p 覆盖 result 进而找到最终正确的索引
while (u-- > 0) {
result[u] = v
v = p[v]
}
return result
}
v3通过使用数组的拷贝,进行存储。通过回溯赋值的方式解决了贪心 + 二分查找替换方式避免发生错误。。。
- 按需编译,体积比vue2更小
- 组合API,类似React Hooks
- 更好的Ts支持
- 暴露自定义渲染API