第 10 卷
制深层响应式,减少不必要重优化);
渲染;
| this关键字 | Composition API 中无 | 函数组件中无this,所有 |
|---|---|---|
| this(setup函数执行时 | 状态和逻辑通过Hooks获取, | |
| 组件实例未完全创建),所有 | 无需处理this绑定问题 | |
| 状态和逻辑通过函数返回和导 | (类组件的常见痛点); |
入获取,避免 this 指向混乱;
三、其他关键差异
- 代码组织方式:
- Vue3:Composition API 允许将相关逻辑(状态、计算属性、监听、生命周期)组织在一起,形成
独立的组合函数,组件代码按“逻辑功能”拆分,而非按“选项类型”拆分;
- React Hooks:函数组件代码按“执行顺序”组织,Hooks必须在组件顶层调用,逻辑复用通过自
定义Hooks抽离,但组件内仍需按顺序调用多个Hooks。
- 对TypeScript的支持:
- Vue3:Composition API 原生支持TS, reactive、 ref 等API可自动推导类型,组合函数的
类型传递更自然;
- React Hooks: useState、 useEffect 等Hooks也支持TS,但复杂状态(如对象数组)的类
型声明略繁琐,需显式指定泛型。
- 学习曲线:
- Vue3:Composition API 对Vue2用户更友好,可逐步迁移(同时使用选项式API和Composition
API),学习成本相对较低;
- React Hooks:需要理解“Hook规则”(调用位置、命名规范)、依赖数组、闭包陷阱等概念,
对新手学习曲线较陡。
25. Vue3的diff算法与Vue2相比的改进 & 对性能的影响
一、Vue2 diff算法的核心逻辑与局限性
- 核心逻辑:
- 采用“双指针遍历”算法,对新旧虚拟DOM树的同层级节点进行逐一对比(深度优先遍历);
- 局限性:
- 对比效率低:无论节点是否为静态节点,都需逐一对比,静态节点的对比产生冗余开销;
- 列表重排性能差:当列表节点需要重新排序(如插入、删除、排序)时,双指针遍历会导致大量节
点的移动、销毁和创建操作,DOM操作开销大;
26. Vue3响应式系统使用Proxy替代Vue2的Object.defineProperty有什
么优势?
Vue3采用Proxy替代Vue2的Object.defineProperty,核心优势在于解决了后者的固有缺陷,同时扩展了响应式能力,具体体现在以下5个核心维度:
- 全量监听对象操作,无需手动干预:
Proxy拦截的是整个目标对象,而非单个属性,天然支持监听对象属性的新增(通过 set 拦截器)
和删除(通过 deleteProperty 拦截器)操作。而Vue2的Object.defineProperty仅能对已存在属性进行拦截,新增/删除属性需通过 Vue.set / this.$delete 手动触发响应式,侵入性强。
- 原生支持数组全量变化监听:
Proxy可直接监听数组的索引修改(如 arr[0] = 10)、长度修改(如 arr.length = 0)
以及所有数组方法的调用(包括非变异方法如 slice),无需重写数组原型。而Vue2需通过重写 7个数组变异方法(push、pop等)实现有限监听,无法覆盖索引/长度修改等场景。
- 懒加载机制优化初始化性能:
Proxy采用“按需代理”策略,对于嵌套对象,仅在访问该嵌套对象时才会对其创建Proxy代理(懒加载),避免了Vue2中初始化时递归遍历对象所有属性的操作,大幅降低了复杂对象的初始化性能
开销。
- 支持更多数据类型:
Proxy不仅支持普通对象、数组,还能完美适配ES6新增的Map、Set、WeakMap、WeakSet等集合类型,以及函数等对象类型。而Object.defineProperty仅适用于普通对象,无法对集合类型实现
有效拦截。
- 更强的拦截能力与更优的依赖管理:
Proxy提供了13种拦截器方法(如 has、 ownKeys、 apply 等),远超 Object.defineProperty仅有的 get / set 拦截能力,可实现更复杂的响应式逻辑。同时,Vue3基
于Proxy实现的依赖收集采用 WeakMap<target, Map<key, Set<effect>>> 的映射结构,依赖存储更高效,且能自动去重,还可借助WeakMap的特性实现依赖自动回收,降低内存泄漏风
险。
- 虚拟DOM是什么?为什么要使用虚拟DOM?
(节点属性)、 children(子节点数组)、 el(对应的真实DOM节点)等属性。
示例(简化VNode结构):
Code block
1const vnode = { 2type: 'div',
| 3 | props: { id: 'app', class: 'container' }, |
|---|---|
| 4 | children: [{ type: 'p', children: 'Hello Vue' }], |
| 5 | el: null //后续会关联真实DOM节点 |
| 6 | } |
二、使用虚拟DOM的核心原因
- 降低真实DOM操作开销,提升性能:
真实DOM是浏览器渲染引擎的核心结构,其操作(创建、修改、删除)会触发浏览器的重排(Reflow)或重绘(Repaint),开销极大。虚拟DOM作为JS对象,操作成本极低,通过先对比虚
拟DOM的变化(即diff算法),再将差异部分批量更新到真实DOM,可大幅减少真实DOM的操作次数,降低性能损耗。
- 实现跨平台渲染:
虚拟DOM是对DOM的抽象,不依赖具体平台的API。基于虚拟DOM,可将相同的渲染逻辑适配到不同平台,如Vue的 @vue/runtime-dom(浏览器端)、 @vue/runtime-weex(Weex移动
端)、 @vue/runtime-node(服务端渲染)等,实现“一次编写,多端运行”。
- 简化复杂DOM操作逻辑:
复杂的DOM更新场景(如列表重排、条件渲染组合)若直接操作真实DOM,需手动处理节点的创建、删除、移动等细节,逻辑繁琐且易出错。虚拟DOM通过抽象描述节点状态,将复杂操作转化为
对JS对象的处理,配合diff算法自动计算更新差异,简化了开发逻辑。
- 为编译优化提供支撑:
Vue3的编译优化(如PatchFlags、静态提升)均基于虚拟DOM实现。编译阶段可标记VNode的动态类型(如动态文本、动态class),运行时diff阶段仅对比标记的动态部分,进一步提升渲染性
能,这一优化逻辑依赖虚拟DOM的抽象特性。
- 虚拟DOM的解析过程是怎样的?
虚拟DOM的“解析过程”本质是从Vue模板到VNode,再到真实DOM的完整流转过程,核心分为3个阶段:模板编译→VNode创建→VNode渲染/更新,具体流程如下:
全站分卷索引 · 12 卷
- 1第 1 卷
- Vue 核心知识点深度解析
- 1. Vue3核心源码精读
- • 核心架构:分为响应式系统( reactivity)、编译系统( compiler)、运行时系统
- • 响应式核心:基于 Proxy 实现响应式,源码核心在 @vue/reactivity 包,包含 effect
- • 组件渲染:采用 VNode(虚拟DOM)描述节点,通过 createVNode 创建虚拟节点, patch
- • 组合式API: setup 函数作为入口, ref(原始类型响应式)、 reactive(对象类型响应
- • 编译优化:引入 PatchFlags(补丁标记)和 StaticNode(静态节点),编译阶段标记动态
- 2. Vuex核心源码精读
- • 核心架构:基于单向数据流设计,核心模块包括 Store(核心类,实例化时初始化状态)、
- • 核心原理:
- 3. Pinia核心源码精读
- • 核心原理:
- 2第 2 卷
- 6. Vue中的依赖收集:触发场景与机制
- 一、依赖收集的触发场景
- 二、依赖收集的核心机制
- • 每个响应式对象的每个属性,对应一个 Dep 类(依赖容器),存储该属性对应的 Watcher
- • 采用“靶心-属性-副作用”的映射关系: WeakMap<响应式对象, Map<属性名,
- • 访问属性时,触发 Proxy 的 get 拦截,调用 track 函数,沿上述映射关系,将当前活跃
- 7. Object.defineProperty的缺点 & Vue3选择Proxy的原因
- 一、Object.defineProperty的潜在缺点/限制
- ◦ 该API只能对已存在的属性进行拦截( get / set),无法感知对象新增属性(如
- ◦ Vue2中需通过 Vue.set / this.$set、 Vue.delete / this.$delete 手动触发响应式
- ◦ Vue2中通过重写数组的7个变异方法(push、pop、shift、unshift、splice、sort、reverse)
- ◦ 若要实现对象全属性响应式,需递归遍历对象的所有属性(包括嵌套对象),对每个属性调用
- 3第 3 卷
- ◦ 示例: <input v-model="msg"> 会被编译为 <input :value="msg"
- 二、不同场景的实现细节
- • 表单元素: v-model 根据元素类型自动匹配属性和事件(文本框: value + input;复选
- • 自定义组件: v-model 是 modelValue prop 和 update:modelValue 事件的语法糖,父
- 9. Vue数据变化时视图的更新机制(即时/异步)
- 一、核心原因
- 二、视图更新的具体机制
- ◦ Vue2:基于 Promise.then(微任务)实现异步队列,兼容环境下会降级为 setTimeout
- ◦ Vue3:基于 queuePostFlushCb 函数,优先使用 Promise.then,其次是
- 10. Vue对象/数组的属性变化监听实现原理
- 一、对象属性变化的监听原理
- 二、数组属性变化的监听原理
- 4第 4 卷
- ◦ 当组件首次进入 keep-alive 时,执行组件的创建生命周期( created、 mounted),
- ◦ 当组件被切换(隐藏)时,Vue不会销毁组件实例,而是将其从DOM中移除,组件状态保留在
- ◦ 当组件再次被切换(显示)时,从 cache 中取出对应的组件实例VNode,重新渲染到DOM
- ◦ max:数字,设置缓存上限,当缓存数量超过 max 时,按照LRU策略删除最久未使用的组件
- ◦ 缓存组件新增两个生命周期: activated(组件激活时触发)、 deactivated(组件失
- 三、具体缓存的内容
- 12. $nextTick方法:原理与用途
- 一、 $nextTick的核心原理
- ◦ 兼容处理:若环境不支持Promise,使用 MutationObserver(微任务),再降级为
- 二、 $nextTick的常见用途
- ◦ 示例:
- ◦ 场景:使用 v-if 控制组件显示隐藏,需要在组件显示后执行初始化逻辑(如第三方插件初始
- 5第 5 卷
- • 解决状态混乱问题:在大型应用中,若组件状态分散管理,会导致状态来源不明确、修改不可控、
- • 提升开发效率:统一的状态管理规范,让团队协作更高效,新开发者可快速理解状态的流转逻辑,
- • 增强应用可维护性:状态与组件解耦,当业务逻辑变更时,只需修改Vuex的Action/Mutation,无
- • 支持高级特性:内置支持状态持久化(配合插件)、模块化拆分、命名空间隔离等高级特性,满足
- 14. Vuex与localStorage在状态管理的不同用途和特性对比
- 一、核心特性对比
- 二、不同用途
- 三、最佳实践
- • 两者结合使用:Vuex负责运行时状态管理,localStorage负责状态持久化,例如:
- • 避免滥用:
- 一、本质区别
- 二、Vuex的核心优势
- 6第 6 卷
- 7第 7 卷
- 8第 8 卷
- 9第 9 卷
- 10第 10 卷
- 11第 11 卷
- 12第 12 卷