2024年最全Vue3之Diff算法源码分析(1),90%的人看完都说好

总结:

  • 函数式编程其实是一种编程思想,它追求更细的粒度,将应用拆分成一组组极小的单元函数,组合调用操作数据流;

  • 它提倡着 纯函数 / 函数复合 / 数据不可变, 谨慎对待函数内的 状态共享 / 依赖外部 / 副作用;

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Tips:

其实我们很难也不需要在面试过程中去完美地阐述出整套思想,这里也只是浅尝辄止,一些个人理解而已。博主也是初级小菜鸟,停留在表面而已,只求对大家能有所帮助,轻喷🤣;

我个人觉得: 这些编程范式之间,其实并不矛盾,各有各的 优劣势

理解和学习它们的理念与优势,合理地 设计融合,将优秀的软件编程思想用于提升我们应用;

所有设计思想,最终的目标一定是使我们的应用更加 解耦颗粒化、易拓展、易测试、高复用,开发更为高效和安全

c1: VNode[],

c2: VNodeArrayChildren,

container: RendererElement,

anchor: RendererNode | null,

parentComponent: ComponentInternalInstance | null,

parentSuspense: SuspenseBoundary | null,

isSVG: boolean,

slotScopeIds: string[] | null,

optimized: boolean

) => {

c1 = c1 || EMPTY_ARR

c2 = c2 || EMPTY_ARR

const oldLength = c1.length

const newLength = c2.length

const commonLength = Math.min(oldLength, newLength)

let i

for (i = 0; i < commonLength; i++) {

const nextChild = (c2[i] = optimized

? cloneIfMounted(c2[i] as VNode)
normalizeVNode(c2[i]))

patch(

c1[i],

nextChild,

container,

null,

parentComponent,

parentSuspense,

isSVG,

slotScopeIds,

optimized

)

}

if (oldLength > newLength) {

// remove old

unmountChildren(

c1,

parentComponent,

parentSuspense,

true,

false,

commonLength

)

} else {

// mount new

mountChildren(

c2,

container,

anchor,

parentComponent,

parentSuspense,

isSVG,

slotScopeIds,

optimized,

commonLength

)

}

}

没有使用patchUnkeyedChildren方法

如果节点相同,继续遍历、否则break、然后从尾部开始遍历、如果旧节点遍历完还有新节点、会用null去patch(就会挂载上去),如果旧的更多就移除旧节点

第五步:乱序的时候、有多余节点就移除节点、之后是移动节点和挂载节点

// can be all-keyed or mixed

const patchKeyedChildren = (

c1: VNode[],

c2: VNodeArrayChildren,

container: RendererElement,

parentAnchor: RendererNode | null,

parentComponent: ComponentInternalInstance | null,

parentSuspense: SuspenseBoundary | null,

isSVG: boolean,

slotScopeIds: string[] | null,

optimized: boolean

) => {

let i = 0

const l2 = c2.length

let e1 = c1.length - 1 // prev ending index

let e2 = l2 - 1 // next ending index

// 1. sync from start

// (a b) c

// (a b) d e

while (i <= e1 && i <= e2) {

const n1 = c1[i]

const n2 = (c2[i] = optimized

? cloneIfMounted(c2[i] as VNode)
normalizeVNode(c2[i]))

if (isSameVNodeType(n1, n2)) {

patch(

n1,

n2,

container,

null,

parentComponent,

parentSuspense,

isSVG,

slotScopeIds,

optimized

)

} else {

break

}

i++

}

// 2. sync from end

// a (b c)

// d e (b c)

while (i <= e1 && i <= e2) {

const n1 = c1[e1]

const n2 = (c2[e2] = optimized

? cloneIfMounted(c2[e2] as VNode)
normalizeVNode(c2[e2]))

if (isSameVNodeType(n1, n2)) {

patch(

n1,

n2,

container,

null,

parentComponent,

parentSuspense,

isSVG,

slotScopeIds,

optimized

)

} else {

break

}

e1–

e2–

}

// 3. common sequence + mount

// (a b)

// (a b) c

// i = 2, e1 = 1, e2 = 2

// (a b)

// c (a b)

// i = 0, e1 = -1, e2 = 0

if (i > e1) {

if (i <= e2) {

const nextPos = e2 + 1

const anchor = nextPos < l2 ? (c2[nextPos] as VNode).el : parentAnchor

while (i <= e2) {

patch(

null,

(c2[i] = optimized

? cloneIfMounted(c2[i] as VNode)
normalizeVNode(c2[i])),

container,

anchor,

parentComponent,

parentSuspense,

isSVG,

slotScopeIds,

optimized

)

i++

}

}

}

// 4. common sequence + unmount

// (a b) c

// (a b)

// i = 2, e1 = 2, e2 = 1

// a (b c)

// (b c)

// i = 0, e1 = 0, e2 = -1

else if (i > e2) {

while (i <= e1) {

unmount(c1[i], parentComponent, parentSuspense, true)

i++

}

}

// 5. unknown sequence

// [i … e1 + 1]: a b [c d e] f g

// [i … e2 + 1]: a b [e d c h] f g

// i = 2, e1 = 4, e2 = 5

else {

const s1 = i // prev starting index

const s2 = i // next starting index

// 5.1 build key:index map for newChildren

const keyToNewIndexMap: Map<string | number | symbol, number> = new Map()

for (i = s2; i <= e2; i++) {

const nextChild = (c2[i] = optimized

? cloneIfMounted(c2[i] as VNode)
normalizeVNode(c2[i]))

if (nextChild.key != null) {

if (DEV && keyToNewIndexMap.has(nextChild.key)) {

warn(

文末

从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。

个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

第二阶段:移动端开发技术

第三阶段:前端常用框架

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;

  • 大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值