文章目录
- 一、watch
- 1.1. 监听ref定义的基本类型数据
- 1.1.1. 单个监听
- 1.1.2. 多个监听
- 1.2. 监听ref定义的对象类型数据
- 1.3. 监听reactive定义的对象类型数据
- 1.4. 监听ref或reactive定义的数据中的某个属性
- 1.5. 组合监听多个数据
- 1.6. 清除watch副作用
一、watch
1.1. 监听ref定义的基本类型数据
监视
ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
1.1.1. 单个监听
let num = ref(1);
watch(num, (newValue, oldValue) => {
console.log(newValue, oldValue);
});
1.1.2. 多个监听
import { ref, watch } from "vue";
let num1 = ref(1);
let num2 = ref(2);
watch([num1, num2], ([newNum1, newNum2], [oldNum1, oldNum2]) => {
console.log(newNum1, newNum2, oldNum1, oldNum2);
});
1.2. 监听ref定义的对象类型数据
监视ref
定义的【对象类型】数据:直接写数据名
注意:
- 监视的是对象的
【地址值】
,若想监视对象内部的属性
,需要手动开启深度监视。- 若修改的是
ref
定义的对象中的属性,因为它们是同一个对象(内存地址不变),所以newValue
和oldValue
都是新值。- 若修改整个
ref
定义的对象,newValue
是新值,oldValue
是旧值,因为不是同一个对象了。
<script setup>
import { ref, watch } from "vue";
let person = ref({
name: "zs",
age: 13,
});
function updateName() {
person.value.name += "~";
}
function updatePerson() {
person.value = {
name: "ls",
age: 18,
};
}
watch(
person,
(newValue, oldValue) => {
console.log(newValue, oldValue);
},
{
deep: true,
}
);
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
</template>
1.3. 监听reactive定义的对象类型数据
reactive
不能定义基本类型数据
监视reactive
定义的【对象类型】数据,且默认开启了深度监视,并且是不可关闭的深度监听。数据中的任何一点蛛丝马迹的变化,都会被监听到。
<script setup>
// 监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。
import { reactive, watch } from "vue";
let person = reactive({
name: "zs",
age: 18,
car: {
c1: "c1",
c2: "c2",
},
});
function updateName() {
person.name += "~";
}
function updatePerson() {
person = Object.assign(person, {
name: "lisi",
age: 13,
});
}
function updateCar() {
person.car.c1 += "1";
}
watch(person, (newValue, oldValue) => {
console.log("person变化了", newValue);
});
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<h1>car: {{ person.car.c1 + "--" + person.car.c2 }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
<button @click="updateCar">修改car</button>
</template>
1.4. 监听ref或reactive定义的数据中的某个属性
监视ref
或reactive
定义的【对象类型】数据中的某个属性,注意点如下:
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
注意点: 若是对象,则监视的是地址值,需要关注对象内部,需要手动开启深度监视。
<script setup>
// 监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。
import { reactive, watch } from "vue";
let person = reactive({
name: "zs",
age: 18,
car: {
c1: "c1",
c2: "c2",
},
});
function updateName() {
person.name += "~";
}
function updatePerson() {
person = Object.assign(person, {
name: "lisi",
age: 13,
});
}
function updateCar() {
person.car.c1 += "1";
}
watch(
() => person.name,
(newValue, oldValue) => {
console.log("person.name变化了", newValue);
}
);
watch(
() => person.car,
(newValue, oldValue) => {
console.log("person.car变化了", newValue);
},
{
deep: true,
}
);
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<h1>car: {{ person.car.c1 + "--" + person.car.c2 }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
<button @click="updateCar">修改car</button>
</template>
1.5. 组合监听多个数据
<template>
<h1>sum: {{ sum }}</h1>
<h1>name: {{ person.name }}</h1>
<button @click="updateSum">修改sum</button>
<button @click="updateName">修改name</button>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from "vue";
let sum = ref(0);
let person = reactive({
name: "zs",
});
function updateName() {
person.name += "~";
}
function updateSum() {
sum.value += 1;
}
watch([sum, person], ([sumNew, personNew], [sumOld, personOld]) => {
console.log(sumNew, personNew, sumOld, personOld);
});
</script>
1.6. 清除watch副作用
watch 的第二个参数是数据发生变化时执行的回调函数。
这个回调函数接受三个参数:新值、旧值,以及一个用于清理副作用的回调函数。该回调函数会在副作用下一次执行前调用,可以用来清除无效的副作用,如等待中的异步请求:
const id = ref(1)
const data = ref(null)
watch(id, async (newValue, oldValue, onCleanup) => {
const { response, cancel } = doAsyncWork(id.value)
// `cancel` 会在 `id` 更改时调用
// 以便取消之前未完成的请求
onCleanup(cancel)
data.value = await response.json()
})
watch 的返回值是一个用来停止该副作用的函数:
const unwatch = watch(() => {})
// ...当该侦听器不再需要时
unwatch()