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)