Skip to content

一、基础认知类

1️⃣ setup 执行时机是什么?和 created 有什么区别?

🎯 考察:生命周期理解

💎 高级回答:

  • setup 在组件实例创建时执行
  • 比 onBeforeMount 更早
  • 相当于 Vue2 的 beforeCreate + created
  • 没有 this
  • 在模板渲染前完成响应式建立

加分点:

setup 本质是 effect 依赖收集前的初始化阶段。

2️⃣ ref 和 reactive 区别?怎么选?

🎯 考察:响应式理解

💎 回答结构:

对比refreactive
数据类型任意只能对象
访问方式.value直接访问
替换整个对象支持不推荐

高级总结:

基本类型用 ref 结构稳定对象用 reactive 需要整体替换对象优先 ref

3️⃣ reactive 为什么不能直接解构?

🎯 考察:响应式丢失原理

💎 原因:

  • 解构后变成普通变量
  • 脱离 Proxy 代理
  • 失去依赖追踪

解决方案:

js
toRefs()

4️⃣ computed 和 watch 区别?

🎯 考察:副作用 vs 派生状态

💎 高级对比:

computedwatch
返回值无返回
缓存
适合派生数据适合副作用

一句话:

computed 是声明式派生 watch 是命令式副作用

5️⃣ watch 和 watchEffect 区别?

🎯 考察依赖收集机制

watchwatchEffect
手动声明依赖自动收集依赖
可拿 oldValue不可
可精确控制更简单

高级补充:

watchEffect 本质是立即执行的 effect。

二、进阶理解类

6️⃣ watch 的 flush 有什么用?

🎯 考察调度机制

js
flush: 'pre'   // 默认
flush: 'post'  // DOM更新后
flush: 'sync'  // 同步

高阶回答:

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 深层变化?

js
{ deep: true }

但高级补充:

深度监听性能差,优先拆分状态。

1️⃣4️⃣ KeepAlive 场景怎么处理数据刷新?

使用:

js
onActivated()

常见场景:

  • 列表页缓存
  • 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)

示例:

js
function useTable() {
  const data = ref([])
  const loading = ref(false)

  const fetchData = async () => {}

  onMounted(fetchData)

  return { data, loading }
}

五、你对 Vue3 hooks 的理解?

Vue3 hooks 本质是基于 effect + scheduler 构建的响应式副作用系统。

ref/reactive 负责状态, computed 负责派生, watch 负责副作用, 生命周期本质是不同阶段注册的 effect。

所有更新都走异步调度队列,避免重复渲染。

在大型项目中我们通过 useXXX 组合式函数进行逻辑复用,并通过 effectScope 管理副作用生命周期。