深色模式
响应式、编译与 Diff 深度原理
27. Vue 2 的 Object.defineProperty 响应式如何工作?
展开答案与追问
参考答案: 初始化时遍历已有属性,把 getter/setter 转为拦截点;读取时由当前 watcher 收集依赖,写入时通知相关 watcher。嵌套对象也需要观察;数组通过封装部分变更方法配合通知。
追问与易错点: 局限:新增/删除属性、直接数组索引赋值与 length 修改有检测限制,常需 Vue.set/Vue.delete 或 splice。Vue 2 响应式
28. Vue 3 的 Proxy 相比 Vue 2 改善在哪里?
展开答案与追问
参考答案: Proxy 面向对象操作,可拦截属性访问、写入、删除、has 和键遍历等;Vue 将这些操作与依赖跟踪连接,支持更多对象变更和集合场景。深层代理可在访问时创建,但数组和 Map/Set 等还需要专门处理。
追问与易错点: Proxy 不意味着任意 JS 值都适合 reactive;WeakMap 中保存依赖也不等于所有内存问题自动消失。深入响应式
29. track、trigger 与 effect 的关系怎么讲?
展开答案与追问
参考答案: 概念上 effect 运行时记录当前活跃副作用;读取响应式属性通过 track 建立“目标/键 → 副作用”的联系;写入通过 trigger 找到相关依赖并运行或调度副作用。渲染与 computed 等利用这一机制。
追问与易错点: 这是概念模型;现代版本内部的数据结构会演进,不能把 WeakMap→Map→Set 的教学模型当作每版逐行源码。
30. 为什么条件切换后要清理旧依赖?
展开答案与追问
参考答案: 例如 flag ? a : b,flag 改变后当前 effect 不应继续订阅不再读取的分支。依赖系统需要更新本轮实际使用的依赖,避免无关触发并减少保留。嵌套 effect 还需要正确恢复外层上下文。
追问与易错点: 教学版只写全局 activeEffect 而不处理嵌套、异常恢复与失效依赖,不能当生产响应式库。
31. computed 的惰性与缓存如何理解?
展开答案与追问
参考答案: computed 跟踪 getter 使用的依赖,依赖变化会让已有结果需要重新评估;读取时可复用仍有效的缓存。它作为派生节点也可以被其他 effect 依赖。外部不可追踪值变化不会自动使缓存失效。
追问与易错点: 避免绝对说每次依赖变化都立即重算,或只改一个 dirty 字段就能概括所有版本实现。
32. Vue 的异步调度与 nextTick 原理是什么?
展开答案与追问
参考答案: 响应式写入可以立即改变内存状态,但组件更新会进入调度队列去重并批处理,常在微任务中刷新。调度还要协调组件父子更新与前后置回调;nextTick 等待相关 DOM 更新队列刷新完成。
追问与易错点: 它不等待浏览器绘制,也不把全部响应式计算都强制变成异步:sync watcher 等有不同路径。
33. Vue 模板到 DOM 的完整链路是什么?
展开答案与追问
参考答案: 模板经解析形成 AST,再经转换生成 render 函数;运行 render 产生 VNode,渲染器挂载 DOM。后续渲染依赖变化触发更新,创建新 VNode 并 patch 旧树。构建工具通常提前编译模板,浏览器不一定携带编译器。
追问与易错点: 来源:渲染机制。虚拟 DOM 是更新表达方式,不保证比所有手写 DOM 更快。
34. 静态提升、Patch Flag 与 Block Tree 如何降低成本?
展开答案与追问
参考答案: 编译器能识别静态内容并缓存/提升,避免不必要的重复创建。Patch Flag 标记动态变化类型,如文本或 class,让 patch 定向检查;Block 记录动态后代,减少遍历静态结构。结构性指令会形成额外块边界。
追问与易错点: 这些优化依赖模板可分析信息;手写 render 或动态结构不一定具有相同收益。渲染机制
35. Vue 2 双端 Diff 与 Vue 3 keyed Diff 如何比较?
展开答案与追问
参考答案: Vue 2 常见 keyed children 算法比较两端的旧新节点并移动或复用,必要时用 key 映射定位。Vue 3 常见路径先同步两端,再处理中间区间,利用新旧索引关系和最长递增子序列减少已复用节点移动。
追问与易错点: 讨论的是特定实现路径,不是所有节点都走 LIS。稳定 key 与节点类型共同决定复用。Vue 渲染器源码
36. 最长递增子序列为什么能减少移动?
展开答案与追问
参考答案: 把新列表已复用节点映射到旧列表索引,递增子序列代表相对顺序已保持的一组节点;最长的一组可保留,其余按锚点调整。例旧 A B C D、新 B C A D,对应 1、2、0、3,可保留 B C D,移动 A。
追问与易错点: LIS 解决此路径的复用节点移动问题,不负责创建、删除或让任意树求出全局最优编辑;常见算法为 O(n log n)。
37. Vue 与 React 的更新思路如何对比?
展开答案与追问
参考答案: Vue 通过响应式读取跟踪组件实际依赖,并借助模板编译信息减少 patch 工作;React 常从 state 更新与组件树协调出发,再结合 memo、调度及编译优化减少工作。二者都有声明式 UI、状态身份和副作用管理问题。
追问与易错点: 避免“Vue 只更新一个 DOM,React 永远全树重绘”这类绝对说法;响应式粒度与组件粒度也不是同一概念。