← 返回目录

第 8 卷

第 8 / 12 卷日期:

  1. 效果:减少函数创建开销,同时确保VNode的事件属性引用稳定,避免因函数引用变化导致的不

必要重渲染。

  1. v-once指令优化:
  2. 原理:标记为 v-once 的节点,编译时标记为“仅渲染一次”的静态节点,首次渲染后缓存

VNode,后续不再重新渲染;

  1. 效果:适用于静态内容或初始化后不再变化的动态内容,减少重复渲染开销。
  2. 动态指令参数优化:
  3. 原理:对于动态指令参数(如 v-bind:[key]="value"),编译时分析可能的参数值范围,

生成更高效的运行时代码;

  1. 效果:避免运行时对所有可能的指令参数进行遍历检查,提升动态指令的解析效率。
  2. Tree-shaking支持:
  3. 原理:编译时根据模板内容,只导入使用到的运行时API(如 createVNode、

patchProps),未使用的API不会被打包;

  1. 效果:减小打包体积,提升应用加载速度。

21. Vue3在性能上优于Vue2的核心原因

Vue3的性能优势是“响应式系统升级+编译优化+运行时优化”多维度协同的结果,核心原因如下:

  1. 响应式系统更高效:
  2. 用Proxy替代Object.defineProperty,减少初始化开销:Vue2需递归遍历对象所有属性并逐个封

装,Vue3采用懒加载机制,仅在访问嵌套对象时才进行Proxy封装,初始化速度提升约50%;

  1. 精准依赖收集:Vue3的依赖收集粒度更细,仅收集实际使用的属性对应的副作用,避免Vue2

中“属性依赖全量更新”的冗余开销,状态变化时只触发相关组件重渲染。

  1. 编译阶段深度优化:
  2. PatchFlags减少虚拟DOM对比开销:运行时仅对比标记的动态内容,静态内容直接跳过,对比效率

提升显著;

  1. 静态提升、预字符串化减少VNode创建开销:静态内容复用VNode或直接转为字符串插入,减少内

存占用和渲染时间;

  1. 缓存事件处理函数避免不必要重渲染:稳定的函数引用确保VNode属性不频繁变化,减少重渲染触

发。

  1. 虚拟DOM与diff算法优化:
  1. diff算法优化:针对数组diff,Vue3引入“最长递增子序列”算法,减少节点移动操作(如列表排

序场景),DOM操作次数显著减少;Vue2的diff算法采用“双指针遍历”,在列表重排时移动操作较多。

  1. 运行时体积优化:
  2. Monorepo架构支持按需导入:应用可只导入使用到的模块(如仅导入响应式模块、编译模块),

未使用的功能(如选项式API的部分辅助函数)不打包,打包体积比Vue2减少约30%;

  1. Tree-shaking清除冗余代码:编译时自动剔除未使用的运行时API,进一步减小包体积,提升加载

速度。

  1. 其他运行时优化:
  2. 组件渲染优化:支持多根节点组件,减少不必要的容器节点嵌套,降低DOM层级和渲染开销;
  3. 异步组件优化:新增Suspense组件,支持异步组件的并行加载和状态统一管理,减少等待时间;
  4. 内存管理优化:使用WeakMap存储响应式依赖,对象销毁时依赖自动回收,减少内存泄漏风险,

长期运行更稳定。

22. Vue3中watch和watchEffect的区别 & 适用场景

一、核心区别

对比维度watchwatchEffect
依赖指定方式显式指定监听目标(如单个响隐式收集依赖,自动监听回调
应式数据、多个响应式数据、函数中使用的所有响应式数据

对象属性)

初始化执行默认不执行,需通过默认初始化执行一次,自动收
immediate: true配置才集回调中的依赖(类似
会初始化执行一次immediate: true的

watch)

参数获取回调函数接收三个参数:新值回调函数仅接收清理函数
(newVal)、旧值(onInvalidate),无法直接
(oldVal)、清理函数获取新旧值,需手动缓存旧值

(onInvalidate),可对比新旧值差异

监听粒度可精确到对象的单个属性监听回调中所有访问的响应式

使用复杂度略高,需手动指定监听目标,更简洁,无需指定监听目标,
配置必要参数(如直接编写业务逻辑,自动收集
immediate、deep)依赖

二、适用场景

  1. watch适用场景:
  2. 需要精确监听某个/某些特定响应式数据的场景(如仅监听用户ID变化,触发接口请求);
  3. 需要对比新旧值差异的场景(如监听表单输入值变化,判断输入是否符合规则,需用到旧值和新

值);

  1. 不需要初始化执行,仅在数据变化时触发逻辑的场景(如用户修改设置后,保存修改记录);
  2. 需要深度监听对象/数组内部变化的场景(通过 deep: true 配置,如监听 state.user 对象的

所有属性变化)。

  1. watchEffect适用场景:
  2. 需要监听多个响应式数据,且只要其中任意一个变化就触发逻辑的场景(如表单多个字段联动校

验);

  1. 需要初始化执行一次,之后自动响应数据变化的场景(如页面加载时获取初始数据,之后监听筛选

条件变化重新获取数据);

  1. 无需对比新旧值,只需根据响应式数据变化执行副作用(如修改DOM、发送请求、操作缓存)的场

景;

  1. 业务逻辑简单,依赖关系明确且无需精确控制监听粒度的场景(如根据多个状态切换页面标

题)。

三、示例对比

Code block

1// watch示例:监听用户名称变化,对比新旧值

2const state = reactive({ user: { name: '张三', age: 20 } })
3watch(
4() => state.user.name,
5(newVal, oldVal, onInvalidate) => {
6console.log(`名称从${oldVal}改为${newVal}`)
7//清理副作用(如取消未完成的请求)
8onInvalidate(() => { /*清理逻辑*/ })
全站分卷索引 · 12 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷