本文整理 Vue3 大厂高频面试真题 ,聚焦 响应式原理、组合式 API、性能优化 3 大核心模块,包含问答解析 + 代码示例 + 原理图解,覆盖初中高级前端面试考点,帮你快速吃透 Vue3 核心知识点,轻松拿下 offer!
一、前言
Vue3 已成为前端面试必考框架,绝大多数公司的面试核心都围绕 3 大方向:
- 响应式原理(Proxy vs Object.defineProperty)
- 组合式 API(Setup 语法糖、生命周期、hooks)
- 性能优化(虚拟 DOM、Diff 算法、懒加载)
本文将这 3 大模块整理成可直接背诵、直接作答的面试题,附带标准答案和加分项,适合面试前突击复习!
模块一:Vue3 响应式原理(高频必问)
1. Vue3 的响应式原理是什么?
标准答案 :
Vue3 使用 ES6 Proxy 代理目标对象,通过 Reflect 操作源对象,实现对对象的读取、赋值、删除、调用 等行为的拦截,在get 时收集依赖 ,set/delete 时触发依赖更新。
核心流程:
- 用
new Proxy(target, handler)创建代理对象 - 访问属性时触发
get,收集当前副作用(effect) - 修改/删除属性时触发
set/deleteProperty - 通知依赖更新,重新渲染视图
加分项 :相比 Vue2 的 Object.defineProperty,Proxy 支持:
- 监听对象全属性(无需递归遍历)
- 监听数组(下标、length、push/pop)
- 支持新增/删除属性
- 性能更高
2. ref 和 reactive 的区别?使用场景?
标准答案:
- ref
- 用于基本数据类型 (string/number/boolean)和引用类型
- 内部通过
value属性挂载值 - 模板中自动解包,无需写
.value
- reactive
- 仅用于对象/数组等引用类型
- 无需
.value,直接访问属性 - 不能直接赋值,会破坏响应式
使用场景:
- 简单类型/单值变量 → ref
- 对象/表单/复杂数据 → reactive
- 函数返回响应式数据 → 优先 ref 或
toRefs
代码示例:
typescript
import { ref, reactive } from 'vue'
// ref
const count = ref(0)
count.value++
// reactive
const user = reactive({ name: 'Vue3', age: 18 })
user.age++
3. toRef / toRefs / toRaw 的作用?
标准答案:
- toRef:将对象的某个属性转为 ref,保持与源对象的响应式连接
- toRefs :将 reactive 对象转为普通对象,每个属性都是 ref,用于解构
- toRaw :获取代理对象的原始对象,跳过响应式,用于性能优化
代码示例:
typescript
import { reactive, toRef, toRefs, toRaw } from 'vue'
const user = reactive({ name: 'test', age: 20 })
// toRef
const name = toRef(user, 'name')
// toRefs 解构不丢失响应式
const { age } = toRefs(user)
// toRaw 获取原始对象
const rawUser = toRaw(user)
4. computed 和 watch 的区别?
标准答案:
- computed 计算属性
- 依赖缓存,只有依赖变化才重新计算
- 必须有 return,不能异步
- 支持 getter/setter
- watch 侦听器
- 不缓存,数据变化就执行
- 支持异步操作
- 用于执行副作用(请求、定时器)
使用场景:
- 数据派生/展示 → computed
- 异步/复杂逻辑 → watch
模块二:组合式 API(Setup 语法糖必考)
5. Vue3 组合式 API 相比选项式 API 的优势?
标准答案:
- 逻辑复用更方便(自定义 Hooks)
- 代码更聚合(相关逻辑写在一起)
- TS 类型推导更友好
- Tree-shaking 友好,打包体积更小
- 大型项目可维护性更强
6. setup 语法糖的优势?
标准答案:
- 更简洁,无需
return - 组件自动注册
- 属性和方法无需暴露,直接使用
- TS 支持更好
- 代码量减少 30%+
7. Vue3 生命周期函数对比 Vue2?
标准答案:
- beforeCreate → setup 内部
- created → setup 内部
- beforeMount → onBeforeMount
- mounted → onMounted
- beforeUpdate → onBeforeUpdate
- updated → onUpdated
- beforeUnmount → onBeforeUnmount
- unmounted → onUnmounted
高频考点 :Vue3 卸载用 onUnmounted,必须清理定时器/事件监听!
8. 什么是自定义 Hooks?如何封装?
标准答案 :
自定义 Hooks 是可复用的逻辑函数,将响应式数据、方法、生命周期封装在一起,实现逻辑复用。
示例(useCount hooks):
typescript
// src/hooks/useCount.ts
import { ref, computed } from 'vue'
export function useCount() {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
const add = () => count.value++
return { count, doubleCount, add }
}
使用:
vue
<script setup lang="ts">
import { useCount } from '@/hooks/useCount'
const { count, doubleCount, add } = useCount()
</script>
9. watch 和 watchEffect 的区别?
标准答案:
- watch :需要显式指定监听源,惰性执行,可获取新值/旧值
- watchEffect :自动收集依赖,立即执行一次,无需指定监听源
使用场景:
- 明确监听某个值 → watch
- 只要依赖变化就执行 → watchEffect
模块三:Vue3 性能优化(大厂最爱问)
10. Vue3 比 Vue2 性能提升在哪里?
标准答案:
- 响应式升级:Proxy 替代 defineProperty
- PatchFlag:只更新动态节点
- 静态提升:静态节点不参与 Diff
- 缓存事件处理函数
- 虚拟 DOM 重构 + 最长递增子序列
- Tree shaking 更友好
11. Vue3 Diff 算法优化点?
标准答案:
- 静态提升,跳过静态节点
- PatchFlag 标记动态内容,精准更新
- 最长递增子序列,减少 DOM 移动
- 只对比有 key 的节点
12. Vue3 项目优化实战手段(必背)
标准答案:
- 路由懒加载
- 组件异步懒加载(defineAsyncComponent)
- v-once / v-memo 减少渲染
- computed 缓存计算结果
- 合理拆分组件,减小重渲染范围
- 图片懒加载、虚拟列表
- Vite 构建分包、压缩、Gzip
- 销毁组件时清除定时器/监听
13. 为什么列表渲染必须加 key?
标准答案 :
key 是 Vue 的唯一标识,帮助 Diff 算法:
- 快速识别节点
- 减少 DOM 操作
- 提升列表更新性能
- 避免列表顺序错乱
严禁:使用随机数/索引作为 key(会导致渲染异常)
14. 组件销毁时为什么要清除副作用?
标准答案 :
不清除会导致:
- 内存泄漏
- 定时器重复执行
- 事件监听异常
- 页面卡顿、报错
示例:
typescript
import { onMounted, onUnmounted } from 'vue'
let timer: number | null = null
onMounted(() => {
timer = setInterval(() => {}, 1000)
})
onUnmounted(() => {
if (timer) clearInterval(timer)
})
二、面试高频手写题
1. 手写简易版响应式(Proxy)
typescript
const target = { name: 'vue3' }
const reactive = (target) => {
return new Proxy(target, {
get(target, key) {
console.log('收集依赖')
return Reflect.get(target, key)
},
set(target, key, value) {
console.log('触发更新')
return Reflect.set(target, key, value)
}
})
}
const proxy = reactive(target)
proxy.name
proxy.name = 'test'
2. 手写路由懒加载
typescript
const routes = [
{
path: '/',
component: () => import('@/views/Home.vue')
}
]
3. 手写异步组件
typescript
import { defineAsyncComponent } from 'vue'
const Modal = defineAsyncComponent(() => import('@/components/Modal.vue'))
三、Vue3 面试答题万能模板(加分神器)
遇到原理题,按这个结构回答:
- 是什么(一句话定义)
- 怎么做(核心流程/API)
- 对比优势(Vue2 vs Vue3)
- 使用场景(实际项目用法)
- 注意事项(避坑点)
四、总结
Vue3 面试核心就 3 点:
- 响应式:Proxy、ref/reactive、toRefs
- 组合式 API:setup、hooks、生命周期
- 性能优化:Diff、懒加载、v-memo、v-once
把本文内容吃透,80%+ Vue3 面试题都能直接秒杀!