高级 Vue 面试题
Vue2 vs Vue3
1. 响应式原理的区别
Vue2:
- 使用
Object.defineProperty() - 无法监听对象新增/删除属性
- 无法监听数组索引和 length 变化
- 需要 $set/$delete 辅助方法
Vue3:
- 使用
Proxy代理整个对象 - 可以监听对象新增/删除属性
- 可以监听数组索引和 length 变化
- 支持 Map、Set、WeakMap、WeakSet
2. 性能优化
Vue3 性能提升:
- 源码体积减少 41%(Tree-shaking)
- 初始化渲染快 55%,更新渲染快 133%
- 内存占用减少 54%
- 编译优化(静态提升、PatchFlag)
3. Composition API vs Options API
Composition API 优势:
- 逻辑复用更方便(自定义 Hook)
- 代码组织更清晰(按功能而非选项类型)
- TypeScript 支持更好
- 更好的 Tree-shaking
响应式系统
1. Vue3 的依赖收集流程
- 创建
Proxy代理对象 - getter 中收集依赖(track)
- setter 中触发更新(trigger)
- 使用 Effect 管理副作用
2. ref 和 reactive 的区别
- ref:返回一个响应式引用对象,通过
.value访问,适用于所有类型 - reactive:返回一个响应式代理对象,只适用于对象类型
3. computed 和 watch 的区别
- computed:基于依赖缓存,只有依赖变化才重新计算,有返回值
- watch:监听数据变化执行回调,无返回值,支持深度监听和立即执行
虚拟 DOM 与 Diff
1. Vue 的 Diff 算法
采用双端 Diff:
- 对比新旧节点列表的头部和尾部
- 通过 key 值寻找可复用节点
- 处理剩余节点
时间复杂度 O(n)。
2. key 的作用?
- 帮助 Vue 识别节点身份
- 提高 Diff 效率
- 维持组件状态
注意:避免使用 index 作为 key,特别是在列表有增删操作时。
3. 静态提升 (Static Hoisting)
Vue3 编译优化:将静态节点提升到渲染函数外部,避免每次渲染时重新创建。
js
// 编译前
const _hoisted_1 = /*#__PURE__*/ createVNode('div', null, 'static text', -1 /* HOISTED */)编译原理
1. Vue 模板编译流程
- 解析 (Parse):将模板字符串解析为 AST
- 转换 (Transform):对 AST 进行转换和优化
- 生成 (Generate):将 AST 生成渲染函数代码
2. PatchFlag 的作用
Vue3 在编译时为动态节点打上标记(PatchFlag),运行时只对比有标记的节点:
TEXT_CHILDREN:动态文本CLASS:动态 classSTYLE:动态 stylePROPS:动态 propsFULL_PROPS:完全动态 propsHYDRATE_EVENTS:需要事件处理
源码相关
1. nextTick 原理
Vue 的异步更新策略:数据变化不会立即更新 DOM,而是将更新操作放入异步队列,在下一个 tick 统一执行。
实现方式优先级:Promise > MutationObserver > setImmediate > setTimeout
2. keep-alive 原理
- 缓存组件实例,避免重复渲染
- 使用 LRU 算法管理缓存
- 提供 include/exclude/max 配置
- 触发 activated/deactivated 生命周期
3. provide/inject 原理
- 依赖注入机制
- provide 提供数据,inject 注入数据
- 数据不是响应式的,需要传入响应式对象
- 用于跨层级组件通信
Vue Router
1. 路由模式
- hash 模式:使用 URL hash,兼容性好,不需要服务端配置
- history 模式:使用 HTML5 History API,URL 更美观,需要服务端配置 fallback
2. 导航守卫
- 全局前置守卫:beforeEach
- 全局解析守卫:beforeResolve
- 全局后置钩子:afterEach
- 路由独享守卫:beforeEnter
- 组件内守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
3. 动态路由匹配
js
const routes = [{ path: '/user/:id', component: User }]通过 $route.params.id 获取参数。
Pinia / Vuex
1. Pinia 相比 Vuex 的优势
- 更简洁的 API
- 完整的 TypeScript 支持
- 支持多个 store
- 模块化设计更简单
- 支持服务端渲染
- 体积更小(1KB)
2. Pinia 核心概念
- State:仓库数据
- Getters:计算属性
- Actions:操作方法(支持异步)
- $patch:批量修改状态
- $reset:重置状态
