watch:是用来监听响应式数据变化的API
watchEffect:vue3中Composition API的一个函数,用于自动追踪响应式依赖并执行副作用回调
|-------------|-----------------------------------------------|-----------------------------------------------------------------------------------------------|----------------------------------|
| 名称 | 概念 | 特点 | 应用 |
| watch | 用于监听响应式数据变化的API | * 懒加载,只有当数据变化的时候执行(设置immediate:true时初始化会加载) * 更加明确需要监听的数据源,更精准的控制回调函数的触发时间 * 可以访问到监听的前一个值和当前值 | * 监听单个或多个特定的数据变化并执行副作用 * 监听多个数据源 |
| watchEffect | vue3中Composition API的一个函数,用于自动追踪响应式依赖并执行副作用回调 | * 首次加载会执行一次,即使是空函数 * 自动追踪所有能访问到的响应式属性,任一属性发生变化都会触发回调函数 * 无法获取前一个值,可以获取当前值 | * 自动追踪依赖并执行 * 初始化时立即执行 |
watch监听demo验证其特性:
{ immediate: true } 表示在数据变化前立即执行回调函数一次
{ deep:true } 表示深度监听,监听数组或对象内部属性的变化
javascript
<template>
<p>
<button type="button" @click="clickMsg">
watch监听msgRef,当前值:{{ msgRef }}
</button>
</p>
</template>
<script setup>
const msgRef = ref("雷gungun");
watch(msgRef, (newVal, oldVal) => {
console.log(
"我是watch,监听msgRef," +
"【前一个值:" +
oldVal +
"】【当前值:" +
newVal +
"】"
);
// { immediate: true }
});
const handleDate = (value) => {
return value < 10 ? "0" + value : value;
};
const clickMsg = () => {
const nowDate =
new Date().getFullYear() +
"-" +
handleDate(new Date().getMonth() + 1) +
"-" +
handleDate(new Date().getDate()) +
" " +
handleDate(new Date().getHours()) +
":" +
handleDate(new Date().getMinutes()) +
":" +
handleDate(new Date().getSeconds());
msgRef.value = "没有什么比空代码执行速度更快" + nowDate;
};
</script>
watch的应用场景一: 监听某个或多个特定的数据变化并执行副作用,例如监听用户登录状态来判断当前页面是跳转到主页还是登录页面;
javascript
<template>
<div>
<select
v-model="loginState"
placeholder="请选择登录状态"
style="width: 200px; height: 30px"
>
<option value="未登录">未登录</option>
<option value="已登录">已登录</option>
</select>
<p>登录状态:{{ loginState }}</p>
</div>
</template>
<script setup>
import { reactive, ref, toRef, toRefs, watch, watchEffect } from "vue";
/**
* 监听某个或多个特定的数据变化并执行副作用
*/
const loginState = ref("");
watch(loginState, (newSate, oldSate) => {
console.log(
"watch监听某个特定的数据变化并执行副作用===旧值:" +
oldSate +
";新值:" +
newSate
);
// 跳转到对应页面
});
</script>
watch的应用场景二:监听多个数据的变化, 比如购物车根据改变单价、个数来计算总价;
javascript
<template>
<div>
<input type="number" v-model="price" placeholder="请输入单价" />
<input type="number" v-model="num" placeholder="请输入个数" />
<p>总价:{{ total }}</p>
</div>
</template>
<script setup>
import { reactive, ref, toRef, toRefs, watch, watchEffect } from "vue";
/**
* 监听多个数据单价、数量或者新值和旧值来计算新的总价
*/
const price = ref(20);
const num = ref(1);
const total = ref(0);
watch(
[price, num],
([newPrice, newNum], [oldPrice, oldNum]) => {
console.log("watch监听多个数据===原值", oldPrice, oldNum);
console.log("watch监听多个数据===新值", newPrice, newNum);
total.value = newPrice * newNum;
},
{ immediate: true }
);
</script>
watchEffect监听demo验证其特性:
javascript
// ref数组
const arr = ref([1, 2]);
const state = reactive({
count: 0,
message: "Hello, Vue3!",
});
watchEffect(() => {
// console.log("我是watchEffect,空函数状态");
// console.log("我是watchEffect,state.count值:" + state.count);
console.log("我是watchEffect,arr值:" + arr.value);
});
watchEffect应用场景一:自动追踪依赖并执行,例如实现实时数据的更新,实时获取现在的日期时间。
javascript
<template>
<div>
当前时间:{{ currentTime }}
</div>
</template>
<script setup>
import {
onUnmounted,
reactive,
ref,
toRef,
toRefs,
watch,
watchEffect,
} from "vue";
const currentTime = ref(new Date().toLocaleString());
watchEffect(() => {
const timer = setInterval(() => {
currentTime.value = new Date().toLocaleString();
}, 1000);
// 清除定时器,防止内存泄漏
onUnmounted(() => {
clearInterval(timer);
});
console.log("实时数据自动更新:", currentTime.value);
});
</script>
或不用watchEffect
javascript
const currentTime = ref("");
onMounted(() => {
setInterval(() => {
currentTime.value = new Date().toLocaleString();
}, 1000);
});
watchEffect应用场景二:我们想要在初始化拿到的数据可以在watchEffect执行,例如初始化更新表格数据。