以2个变量为例:
方法一:使用多个 watch
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
// 分别监听两个变量
watch(count, (newValue, oldValue) => {
console.log('count changed:', newValue, oldValue);
});
watch(name, (newValue, oldValue) => {
console.log('name changed:', newValue, oldValue);
});
</script>
方法二:使用 watch 监听数组(推荐)
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
// 同时监听两个变量
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log('count changed:', newCount, oldCount);
console.log('name changed:', newName, oldName);
});
</script>
方法三:使用 watchEffect(自动追踪依赖)
<script setup>
import { ref, watchEffect } from 'vue';
const count = ref(0);
const name = ref('');
// 自动追踪依赖的变量
watchEffect(() => {
console.log('count:', count.value);
console.log('name:', name.value);
// 这里可以执行需要同时监听两个变量的逻辑
});
</script>
方法四:带有配置选项的监听
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
// 带有配置选项的监听
watch(
[count, name],
([newCount, newName], [oldCount, oldName]) => {
console.log('数据变化了:', { newCount, newName, oldCount, oldName });
},
{
immediate: true, // 立即执行一次
deep: true, // 深度监听(如果变量是对象或数组)
}
);
</script>
方法五:监听 reactive 对象的多个属性
<script setup>
import { reactive, watch, toRefs } from 'vue';
const state = reactive({
count: 0,
name: '',
active: true
});
// 监听 reactive 对象的多个属性
watch(
() => [state.count, state.name],
([newCount, newName], [oldCount, oldName]) => {
console.log('count or name changed:', { newCount, newName });
}
);
// 或者使用 toRefs
const { count, name } = toRefs(state);
watch([count, name], ([newCount, newName]) => {
console.log('count or name changed:', newCount, newName);
});
</script>
方法六:条件监听(只有特定条件时才执行)
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
watch(
[count, name],
([newCount, newName]) => {
// 只有满足特定条件时才执行
if (newCount > 5 && newName !== '') {
console.log('条件满足:', newCount, newName);
}
}
);
</script>
方法七:防抖的监听
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
let timeoutId = null;
watch(
[count, name],
([newCount, newName]) => {
// 防抖处理
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
console.log('防抖后的变化:', newCount, newName);
}, 300);
}
);
</script>
完整示例
<template>
<div>
<button @click="count++">Count: {{ count }}</button>
<input v-model="name" placeholder="Enter name">
<p>变化日志: {{ log }}</p>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
const count = ref(0);
const name = ref('');
const log = ref('');
// 同时监听两个变量
watch(
[count, name],
([newCount, newName], [oldCount, oldName]) => {
const message = `Count: ${oldCount} → ${newCount}, Name: "${oldName}" → "${newName}"`;
log.value = message;
console.log(message);
},
{ immediate: true }
);
</script>
推荐使用方法二(watch 监听数组),因为它:
-
代码清晰,明确知道监听哪些变量
-
可以同时获取新旧值
-
性能较好,只在指定变量变化时触发
-
支持配置选项(immediate、deep等)
根据你的具体需求选择合适的方法。如果只是需要响应式地执行某些逻辑,watchEffect 可能更简洁;如果需要精确控制监听哪些变量和获取新旧值,使用 watch 数组更合适。