Vue3 hooks 对比
# 一、基础认知类
# 1️⃣ setup 执行时机是什么?和 created 有什么区别?
🎯 考察:生命周期理解
💎 高级回答:
- setup 在组件实例创建时执行
- 比 onBeforeMount 更早
- 相当于 Vue2 的 beforeCreate + created
- 没有 this
- 在模板渲染前完成响应式建立
加分点:
setup 本质是 effect 依赖收集前的初始化阶段。
# 2️⃣ ref 和 reactive 区别?怎么选?
🎯 考察:响应式理解
💎 回答结构:
| 对比 | ref | reactive |
|---|---|---|
| 数据类型 | 任意 | 只能对象 |
| 访问方式 | .value | 直接访问 |
| 替换整个对象 | 支持 | 不推荐 |
高级总结:
基本类型用 ref 结构稳定对象用 reactive 需要整体替换对象优先 ref
# 3️⃣ reactive 为什么不能直接解构?
🎯 考察:响应式丢失原理
💎 原因:
- 解构后变成普通变量
- 脱离 Proxy 代理
- 失去依赖追踪
解决方案:
toRefs()
1
# 4️⃣ computed 和 watch 区别?
🎯 考察:副作用 vs 派生状态
💎 高级对比:
| computed | watch |
|---|---|
| 返回值 | 无返回 |
| 缓存 | 有 |
| 适合派生数据 | 适合副作用 |
一句话:
computed 是声明式派生 watch 是命令式副作用
# 5️⃣ watch 和 watchEffect 区别?
🎯 考察依赖收集机制
| watch | watchEffect |
|---|---|
| 手动声明依赖 | 自动收集依赖 |
| 可拿 oldValue | 不可 |
| 可精确控制 | 更简单 |
高级补充:
watchEffect 本质是立即执行的 effect。
# 二、进阶理解类
# 6️⃣ watch 的 flush 有什么用?
🎯 考察调度机制
flush: 'pre' // 默认
flush: 'post' // DOM更新后
flush: 'sync' // 同步
1
2
3
2
3
高阶回答:
DOM 操作类逻辑必须用 post,否则拿不到更新后的 DOM。
# 7️⃣ 为什么说 Vue3 更新是异步批处理?
🎯 考察调度机制
回答结构:
- 组件更新基于 effect
- 更新任务进入 job queue
- 微任务中统一执行
- 避免重复渲染
# 8️⃣ nextTick 原理是什么?
🎯 考察微任务理解
高级回答:
nextTick 本质是等待当前更新队列 flush 完成。
# 9️⃣ 生命周期内部本质是什么?
🎯 考察底层认知
回答:
本质是不同阶段注册的 effect 回调。
# 🔟 onMounted 和 watchEffect 谁更早?
答案:
- setup
- watchEffect(立即执行)
- onMounted(DOM挂载后)
# 三、场景题(高频)
# 1️⃣1️⃣ 什么时候必须用 watch 而不是 computed?
💎 回答:
- 发请求
- 写 localStorage
- 操作 DOM
- 日志上报
一句话:
有副作用必须用 watch。
# 1️⃣2️⃣ 如何避免 watch 死循环?
常见原因:
- watch 里修改被监听值
解决:
- 使用条件判断
- 使用 flush post
- 分离状态
# 1️⃣3️⃣ 如何监听 reactive 深层变化?
{ deep: true }
1
但高级补充:
深度监听性能差,优先拆分状态。
# 1️⃣4️⃣ KeepAlive 场景怎么处理数据刷新?
使用:
onActivated()
1
常见场景:
- 列表页缓存
- tab页面
# 1️⃣5️⃣ 组件卸载后 watch 会自动销毁吗?
答案:
✅ 会自动清理
因为:
watch 绑定在当前组件 effect scope 下。
# 四、架构级问题(拉开差距)
# 1️⃣6️⃣ 什么是 effectScope?
高级回答:
effectScope 是 Vue3 用来管理副作用集合的机制, 组件本身就是一个 effectScope。
用途:
- 手动创建作用域
- 批量销毁 effect
# 1️⃣7️⃣ 为什么组合式函数不会内存泄漏?
回答:
- 因为内部 watch 属于当前组件 scope
- 组件卸载自动清理
# 1️⃣8️⃣ 为什么 Vue3 性能比 Vue2 好?
回答结构:
- Proxy 代替 defineProperty
- 精确依赖收集
- 静态提升
- patch flag
- 编译优化
# 1️⃣9️⃣ Vue3 如何避免重复依赖收集?
答:
- 使用 activeEffect
- 使用依赖 Map 结构
- 去重收集
# 2️⃣0️⃣ 如何设计大型 useXXX hooks?
高级回答结构:
- 状态层(ref/reactive)
- 副作用层(watch)
- 生命周期层(onMounted)
- 对外暴露层(return)
示例:
function useTable() {
const data = ref([])
const loading = ref(false)
const fetchData = async () => {}
onMounted(fetchData)
return { data, loading }
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 五、你对 Vue3 hooks 的理解?
Vue3 hooks 本质是基于 effect + scheduler 构建的响应式副作用系统。
ref/reactive 负责状态, computed 负责派生, watch 负责副作用, 生命周期本质是不同阶段注册的 effect。
所有更新都走异步调度队列,避免重复渲染。
在大型项目中我们通过 useXXX 组合式函数进行逻辑复用,并通过 effectScope 管理副作用生命周期。
上次更新: 2026/03/04, 09:44:50