首先watch和watchEffect都是监听器,但在写法和使用上有所区别。
引用watch和watchEffect
import { watchEffect, watch } from "vue";
watch
- 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行
- 参数可以拿到当前值和原始值
- 需要传递要侦听的内容
- 可以侦听多个数据的变化,用一个侦听起承载
对基本数据类型进行监听
<template>
Name: <input v-model="name" />
</template>
<script setup>
const name = ref('zhangsan')
watch(name, (curVal, prevVal) => {
console.log(curVal, prevVal)
})
<script>
对引用类型进行监听
<template>
Name: <input v-model="name" /> englishName: <input v-model="englishName" />
</template>
<script setup>
const nameObj = reactive({ name: "leilei", englishName: "bob" });
//监听一个数据
watch(
() => nameObj.name,
(curVal, prevVal) => {
console.log(curVal, prevVal);
}
);
//监听多个数据
watch(
[() => nameObj.name, () => nameObj.name],
([curName, curEng], [prevName, curEng]) => {
console.log(curName, curEng, "----", prevName, curEng);
setTimeout(() => {
stop();
}, 5000);
}
);
const { name, englishName } = toRefs(nameObj);
</script>
watch取消监听
const stop1 = watch(
[() => nameObj.name, () => nameObj.name],
([curName, curEng], [prevName, curEng]) => {
console.log(curName, curEng, "----", prevName, curEng);
setTimeout(() => {
stop();
}, 5000);
}
);
watch也可以变为非惰性的 立即执行的 添加第三个参数 immediate: true
watch(
[() => nameObj.name, () => nameObj.name],
([curName, curEng], [prevName, curEng]) => {
console.log(curName, curEng, "----", prevName, curEng);
setTimeout(() => {
stop();
}, 5000);
},
{
immediate: true,
}
);
watchEffect
- 立即执行,没有惰性,页面的首次加载就会执行。
- 没有过多的参数,只有一个回调函数
- 自动检测内部代码,代码中有依赖就会执行
- 不需要传递要侦听的内容,会自动感知代码依赖
- 无法获取到原值,只能得到变化后的值
- 异步的操作放在这里会更加合适
watchEffect(() => {
console.log(state.count);
console.log(state.name);
/* 初始化时打印:
0
zs
1秒后打印:
1
ls
*/
});
setTimeout(() => {
state.count++;
state.name = "ls";
}, 1000);
watchEffect取消监听
const stop = watchEffect(() => {
console.log(nameObj.name);
setTimeout(() => {
stop();
}, 5000);
});
根据以上特征,我们可以自行选择使用哪一个监听器