watchEffect 与 watch的区别
watch
与 watchEffect
最大的区别是一个是“手动挡”一个是“自动挡”
1. watchEffect
watchEffect
会 自动收集依赖,当依赖的数据发生变化时,执行回调函数。
1.1. 特点
- 不需要显式指定要监听的变量,它会在回调里 自动追踪用到的响应式数据。
- 初始化时 会立即执行一次。
- 常用于逻辑简单的场景,比如打印、发请求、DOM 操作等。
1.2. 示例:
<script setup>import { ref, watchEffect } from 'vue';const count = ref(0);const name = ref('张三');// 1. 定义 watchEffectwatchEffect(() => {// 这是一个副作用函数console.log(`当前计数值是: ${count.value}`);});// 2. 1秒后修改 countsetTimeout(() => {count.value++;}, 1000);// 3. 2秒后修改 namesetTimeout(() => {name.value = '李四';}, 2000);
</script>
执行逻辑是这样的:当组件初始化时,watchEffect 会立即执行一次其内部的副作用函数。在首次执行的过程中,它会像一个智能的侦探,自动“扫描”并“记录”下函数内部所有被读取过的响应式数据。例如,如果函数中用到了 count.value
,watchEffect
就会在内部将 count 标记为自己的依赖;而函数中没有用到的 name
则不会被追踪。(其实简单来说,就是在回调函数里面写了哪些变量它会自动监听)
2. watch
watch
需要你 显式指定要监听的源,变化时才会触发回调。
2.1. 特点
- 需要手动指定监听的 ref、reactive 属性 或 getter 函数。
- 默认不会立即执行,除非你传
{ immediate: true }
。 - 可以拿到 新值和旧值,适合复杂逻辑(对比前后值、条件判断)。
2.2. 示例:
<script setup>import { ref, watch } from 'vue'const count = ref(0)watch(count, (newValue, oldValue) => {console.log(`count 从 ${oldValue} 变成了 ${newValue}`)}, { immediate: true })
</script>
每次 count.value
改变时,回调会执行,并且能拿到新旧值。
3. 总结
特性 |
|
|
是否需要手动指定依赖 | ❌ 自动收集 | ✅ 手动指定 |
是否立即执行 | ✅ 默认立即执行 | ❌ 默认不执行(可 ) |
是否有新旧值 | ❌ 没有 | ✅ 有 |
适用场景 | 简单副作用(打印、网络请求、DOM 操作) | 精确控制,复杂逻辑(需要新旧值对比) |
选择的时候:如果页面上一个逻辑需要很多值,且不需要新旧值对比的时候,选择 watchEfect
试一个很好的选择,这样就不需要写很长的监听值,比如:watch([category, priceRange, inStock], ...)