第 3 卷
◦ 示例: <input v-model="msg"> 会被编译为 <input :value="msg"
二、不同场景的实现细节
• 表单元素: v-model 根据元素类型自动匹配属性和事件(文本框: value + input;复选
框: checked + change);
• 自定义组件: v-model 是 modelValue prop 和 update:modelValue 事件的语法糖,父
组件通过 v-model 传递数据,子组件通过 emit('update:modelValue', 新值) 更新父组件数据,实现双向绑定。
9. Vue数据变化时视图的更新机制(即时/异步)
Vue中数据对象属性值改变时,视图更新是异步的,而非即时的。
一、核心原因
Vue采用异步更新队列的设计,目的是:
- 避免重复更新:若在同一事件循环中多次修改同一数据(或多个数据),Vue会将多次更新请求合
并为一次,减少DOM操作次数,提升性能;
- 避免中间状态展示:若同步更新,可能导致视图展示数据的中间状态(如多次修改数据,视图频繁
闪烁),异步更新可确保视图最终展示的是数据的最终状态。
二、视图更新的具体机制
- 触发更新:当响应式数据变化时, trigger 函数会触发对应的 Effect(如组件渲染副作
用),Vue不会立即执行 Effect,而是将其加入异步更新队列;
- 队列去重:Vue会对更新队列进行去重处理(同一组件的 Effect 只会被添加一次),避免重复渲
染;
- 执行队列:Vue会在当前事件循环的微任务阶段(优先)或下一个宏任务阶段执行更新队列中的
Effect,完成组件渲染和DOM更新;
◦ Vue2:基于 Promise.then(微任务)实现异步队列,兼容环境下会降级为 setTimeout
(宏任务);
◦ Vue3:基于 queuePostFlushCb 函数,优先使用 Promise.then,其次是
MutationObserver,最后是 setTimeout;
- 更新完成:异步队列执行完毕后,视图更新完成,若需要在视图更新后执行逻辑,可使用
$nextTick(Vue2)或 nextTick(Vue3)。
4this.msg = '3' 5// 视图最终展示'3',仅执行一次DOM更新
10. Vue对象/数组的属性变化监听实现原理
Vue对对象和数组的监听机制做了差异化设计,适配两者的特性,核心实现如下:
一、对象属性变化的监听原理
Vue2 实现
- 递归遍历对象的所有已有属性,对每个属性调用 Object.defineProperty,定义 get(依
赖收集)和 set(依赖触发)拦截器;
- 当访问对象属性时,触发 get 拦截,收集当前副作用(Watcher);
- 当修改对象属性值时,触发 set 拦截,通知依赖集合(Dep)中的Watcher更新;
- 对于新增属性:无法自动监听,需通过 Vue.set(obj, key, value) 手动为新增属性添加
Object.defineProperty 拦截,并触发依赖更新;
- 对于删除属性:无法自动监听,需通过 Vue.delete(obj, key) 手动删除属性并触发依赖更
新;
- 对于嵌套对象:递归遍历嵌套对象,逐层为属性添加拦截,实现深层响应式。
Vue3 实现
- 通过 Proxy 创建对象的代理,拦截整个对象的操作,无需递归遍历已有属性;
2.get 拦截器:访问对象属性时,收集依赖;若属性值是嵌套对象,按需对嵌套对象创建 Proxy (懒代理),实现深层响应式;
3.set 拦截器:修改属性值(或新增属性)时,触发依赖更新,并返回 true 表示操作成功;
4.deleteProperty 拦截器:删除对象属性时,触发依赖更新,并返回 true 表示操作成功;
- 无需手动处理新增/删除属性,原生支持深层对象监听,性能更优。
二、数组属性变化的监听原理
Vue2 实现(缺陷明显,需特殊处理)
- 重写数组原型方法:Vue2会创建一个数组原型的“副本”,重写其中7个变异方法(push、pop、
- 无法监听的场景:
- 数组索引修改(如 arr[0] = 123);
- 数组长度修改(如 arr.length = 0);
- 非变异方法调用(如 arr.slice(0, 1),不会修改原数组);
- 对于上述无法监听的场景,需通过 Vue.set(arr, index, value) 手动触发更新。
Vue3 实现(原生支持,无需特殊处理)
- 通过 Proxy 拦截数组的所有操作,无需重写原型方法;
2.get 拦截器:访问数组元素(索引)、长度、调用数组方法时,收集依赖;
3.set 拦截器:修改数组索引值、修改数组长度时,触发依赖更新;
- 无论调用何种数组方法(变异/非变异)、修改索引/长度,都能被 Proxy 感知,原生支持数组的
全量变化监听,无需手动干预。
11. keep-alive组件:作用、实现机制、缓存内容
一、 keep-alive的核心作用
keep-alive 是Vue内置的抽象组件(自身不会渲染为真实DOM),核心作用是:
- 缓存组件实例:当组件在 keep-alive 内被切换时,不会被销毁(即不执行
unmounted / destroyed 生命周期),而是被缓存起来;
- 保留组件状态:缓存后的组件再次激活时,会保留其之前的状态(如表单输入内容、滚动条位置
等),无需重新初始化数据;
- 提升性能:避免组件频繁创建( mounted / created)和销毁,减少DOM操作和数据请求开
销,提升页面切换流畅度。
二、实现机制
keep-alive 的实现依赖Vue的组件生命周期和缓存容器,核心流程如下:
- 缓存容器: keep-alive 内部维护两个缓存容器(对象/Map):
- cache:存储缓存的组件实例(key:组件的 name 或 cid,value:组件实例VNode);
◦ keys:存储缓存组件的key列表,用于控制缓存上限( max 属性),实现LRU(最近最少使
用)缓存策略;
全站分卷索引 · 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 卷