# Vue

# 响应式/双向绑定

# Vue2

数据劫持+观察者模式

# 数据劫持

当面试官问你 Vue 响应式原理,你可以这么回答他 (opens new window)

Object.defineProperty将属性进行劫持

每个属性都拥有自己的 dep 属性,存放他所依赖的 watcher(依赖收集)

当某个属性修改时,触发 dep.notify() 通知每个需要更新的 watcher

Observer 负责将数据转换成 getter/setter 形式; Dep 负责管理数据的依赖列表;是一个观察者模式,上游对接 Observer,下游对接 Watcher Watcher 是实际上的数据依赖,负责将数据的变化转发到外界(渲染、回调); 首先将 data 传入 Observer 转成 getter/setter 形式;当 Watcher 实例读取数据时,会触发 getter,被收集到 Dep 仓库中;当数据更新时,触发 setter,通知 Dep 仓库中的所有 Watcher 实例更新,Watcher 实例负责通知外界

# Vue3

effect 副作用函数 替代 Vue2 的 watcher 来触发修改时的渲染

# diff

15 张图,20 分钟吃透 Diff 算法核心原理,我说的!!! (opens new window)

# Vue2

Diff 算法是一种对比算法。对比两者是旧虚拟 DOM 和新虚拟 DOM,对比出是哪个虚拟节点更改了,找出这个虚拟节点,并只更新这个虚拟节点所对应的真实节点,而不用更新其他数据没发生改变的节点,实现精准地更新真实 DOM,进而提高效率

原理:

Diff 算法比较只会在同层级进行, 不会跨层级比较。 所以 Diff 算法是:深度优先算法

updateChildren:

首尾指针法 双端比较算法

交叉对比 4 次

如果元素相同 指针移动

用 index 做 key

先比对 key 的值 如果相同 做比对 元素一直 并且没变 就不进行变更元素直接复用元素

相同 key 的节点会去进行 patchVnode 更新文本 如果结点变了 还是会更新

所以 唯一 key 的好处就是 当元素就算是进行了 patchVnode,也不会执行里面复杂的更新操作

介绍比对时间

# Vue3

深入浅出虚拟 DOM 和 Diff 算法,及 Vue2 与 Vue3 中的区别 (opens new window)

  • 事件缓存

    会先判断事件是否被缓存

  • 添加静态标记

    对于单个有动态绑定的元素来说,我们可以在编译时推断出大量信息 去给元素一个标记 判断他是哪一种动态类型 结点如果没有动态数据 会被标记为静态结点 HOISTED = -1

  • 静态提升

    模板里面没有动态变量

  • patchKeyedChildren

一个区块内部的树结构打平

包含多个根节点的模板被表示为一个片段 (fragment),大多数情况下,我们可以确定其顺序是永远不变的,所以这部分信息就可以提供给运行时作为一个修补标记

template-explorer (opens new window)

去头尾的最长递增子序列算法

解析 Vue3.0 的 dom-diff 核心算法 (opens new window) 最长递增子序列的作用是找到最少移动次数

# Vue2 编译原理

上次更新: 5/4/2022, 8:34:47 PM