📚前端面试题速记
Q10

Vue 3 的 watch 和 watchEffect 有何区别?

速记答案(30 秒)

watch:显式指定依赖,能拿到 newVal/oldVal。watchEffect:不写依赖,自动收集,无法直接拿 oldVal,更适合简单的声明式副作用。

📖 详细讲解

标准面试回答(推荐记住)

watch 需要显式指定监听的数据源,回调函数能获取新旧值,适合需要对比变化或有条件执行的场景。watchEffect 会自动收集回调中用到的响应式依赖,立即执行一次,更接近"响应式副作用",适合简单的同步操作。

watch vs watchEffect 详细对比

特性 watch watchEffect
依赖收集 显式指定 自动收集(同步执行期间访问的)
首次执行 默认不执行 (lazy) 默认立即执行 (immediate)
oldVal ✅ 支持 ❌ 不支持
异步处理 较灵活 必须在同步逻辑中收集依赖
清理副作用 onCleanup onCleanup

适用场景

  • watch:

    • 当你需要侦听一个特定的数据源。
    • 当你需要在回调中访问改变前后的值。
    • 只有在数据变化时才执行回调(配置 immediate: false)。
  • watchEffect:

    • 对于有多个依赖项的副作用。
    • 初始化时就需要执行一次的逻辑(如请求接口)。
    • 不需要访问 oldVal。

面试要点

  • 清楚两者的使用场景区别
  • 理解自动收集依赖的原理
  • 知道 watch 的立即执行选项

💻 代码示例

watch vs watchEffect
import { ref, watch, watchEffect } from 'vue'

const count = ref(0)
const name = ref('Vue')

// watch - 显式指定依赖
watch(count, (newVal, oldVal) => {
  console.log(`count: ${oldVal} -> ${newVal}`)
})

// watch 多个源
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
  console.log('多个值变化')
})

// watchEffect - 自动收集依赖
watchEffect(() => {
  // 自动追踪 count.value 和 name.value
  console.log(`count: ${count.value}, name: ${name.value}`)
})
watch 与 watchEffect 对比演示(可交互)
🎨 效果预览