Vue 3 中的 watch:如何监视 reactive 或 ref 定义的对象类型数据中的某个属性
Vue 3 中的 watch:如何监视 reactive 或 ref 定义的对象类型数据中的某个属性
在 Vue 3 中,watch 不仅可以监视整个对象,还可以监视对象中的某个属性。监视对象中的某个属性时,需要特别注意如何正确地指定监视的目标。接下来,我们将详细学习如何使用 watch 监视对象中的某个属性,并理解其背后的原理。
一、监视对象中的某个属性
(一)问题描述
reactive 和 ref 都可以定义对象类型的数据。监视对象中的某个属性时,watch 的行为会有所不同。默认情况下,watch 会监视整个对象的变化,但如果只想监视对象中的某个属性,需要特别处理。
(二)示例代码
HTML复制
<template>
<div>
<h1>情况四:监视对象中的某个属性</h1>
<p>姓名:{{ person.name }}</p>
<p>年龄:{{ person.age }}</p>
<p>第一台车:{{ person.car.c1 }}</p>
<p>第二台车:{{ person.car.c2 }}</p>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeCar1">修改第一台车</button>
<button @click="changeCar2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script setup lang="ts">
import { reactive, watch } from 'vue';
const person = reactive({
name: '张三',
age: 18,
car: {
c1: '奔驰',
c2: '宝马'
}
});
const changeName = () => {
person.name += '波浪';
};
const changeAge = () => {
person.age += 1;
};
const changeCar1 = () => {
person.car.c1 = '奥迪';
};
const changeCar2 = () => {
person.car.c2 = '大众';
};
const changeCar = () => {
person.car = {
c1: '雅迪',
c2: '爱玛'
};
};
watch(() => person.name, (newValue, oldValue) => {
console.log('name 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
});
watch(() => person.age, (newValue, oldValue) => {
console.log('age 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
});
watch(() => person.car, (newValue, oldValue) => {
console.log('car 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
}, { deep: true });
</script>
(三)解释
-
定义响应式对象:使用
reactive定义person,包含name、age和car。 -
修改对象属性:通过
changeName、changeAge、changeCar1、changeCar2和changeCar方法修改对象的属性。
如何在Vue 3 中的 watch:如何监视 reactive 或 ref 定义的对象类型数据中的某个属性呢?
这就是重点了。
- 监视对象属性:
-
使用
watch监视person.name和person.age,直接写成函数形式。 -
使用
watch监视person.car,写成函数形式,并开启深度监视(deep: true)。这样既能监视car,又能监视car中的属性变化
(四)运行效果
-
点击“修改名字”按钮,
name属性会变化,触发watch。 -
点击“修改年龄”按钮,
age属性会变化,触发watch。 -
点击“修改第一台车”和“修改第二台车”按钮,
car属性会变化,触发watch。 -
点击“修改整个车”按钮,
car属性会整体变化,触发watch。
二、watch 的行为
(一)监视基本类型属性
监视对象中的基本类型属性(如 name 和 age)时,需要将属性包装成函数形式:
JavaScript复制
watch(() => person.name, (newValue, oldValue) => {
console.log('name 变化了');
});
(二)监视对象类型属性
监视对象中的对象类型属性(如 car)时,可以直接写属性路径,但建议写成函数形式,并开启深度监视:
JavaScript复制
watch(() => person.car, (newValue, oldValue) => {
console.log('car 变化了');
}, { deep: true });
(三)newValue 和 oldValue
-
newValue:变化后的值。 -
oldValue:变化前的值。 -
特殊情况:如果监视的是对象类型属性,
newValue和oldValue会是同一个对象,除非整体替换对象。
(四)示例代码
HTML复制
<template>
<div>
<h1>情况四:监视对象中的某个属性</h1>
<p>姓名:{{ person.name }}</p>
<p>年龄:{{ person.age }}</p>
<p>第一台车:{{ person.car.c1 }}</p>
<p>第二台车:{{ person.car.c2 }}</p>
<button @click="changeName">修改名字</button>
<button @click="changeAge">修改年龄</button>
<button @click="changeCar1">修改第一台车</button>
<button @click="changeCar2">修改第二台车</button>
<button @click="changeCar">修改整个车</button>
</div>
</template>
<script setup lang="ts">
import { reactive, watch } from 'vue';
const person = reactive({
name: '张三',
age: 18,
car: {
c1: '奔驰',
c2: '宝马'
}
});
const changeName = () => {
person.name += '波浪';
};
const changeAge = () => {
person.age += 1;
};
const changeCar1 = () => {
person.car.c1 = '奥迪';
};
const changeCar2 = () => {
person.car.c2 = '大众';
};
const changeCar = () => {
person.car = {
c1: '雅迪',
c2: '爱玛'
};
};
watch(() => person.name, (newValue, oldValue) => {
console.log('name 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
});
watch(() => person.age, (newValue, oldValue) => {
console.log('age 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
});
watch(() => person.car, (newValue, oldValue) => {
console.log('car 变化了');
console.log('新的值:', newValue);
console.log('旧的值:', oldValue);
}, { deep: true });
</script>
(五)运行效果
-
点击“修改名字”和“修改年龄”按钮时,
watch会触发回调函数。 -
点击“修改第一台车”和“修改第二台车”按钮时,
watch会触发回调函数。 -
点击“修改整个车”按钮时,
watch会触发回调函数。
三、最佳实践
(一)监视对象中的某个属性
监视对象中的某个属性时,建议写成函数形式:
JavaScript复制
watch(() => person.name, (newValue, oldValue) => {
console.log('name 变化了');
});
(二)监视对象类型属性
监视对象中的对象类型属性时,建议写成函数形式,并开启深度监视:
JavaScript复制
watch(() => person.car, (newValue, oldValue) => {
console.log('car 变化了');
}, { deep: true });
(三)总结
-
监视基本类型属性:写成函数形式。
-
监视对象类型属性:写成函数形式,并开启深度监视(
deep: true)。
- 点赞
- 收藏
- 关注作者
评论(0)