Vue 3 中的 watch:如何监视 reactive 或 ref 定义的对象类型数据中的某个属性

举报
周杰伦本人 发表于 2025/01/22 14:27:08 2025/01/22
【摘要】 Vue 3 中的 watch:如何监视 reactive 或 ref 定义的对象类型数据中的某个属性在 Vue 3 中,watch 不仅可以监视整个对象,还可以监视对象中的某个属性。监视对象中的某个属性时,需要特别注意如何正确地指定监视的目标。接下来,我们将详细学习如何使用 watch 监视对象中的某个属性,并理解其背后的原理。一、监视对象中的某个属性(一)问题描述reactive 和 re...

Vue 3 中的 watch:如何监视 reactiveref 定义的对象类型数据中的某个属性

在 Vue 3 中,watch 不仅可以监视整个对象,还可以监视对象中的某个属性。监视对象中的某个属性时,需要特别注意如何正确地指定监视的目标。接下来,我们将详细学习如何使用 watch 监视对象中的某个属性,并理解其背后的原理。


一、监视对象中的某个属性

(一)问题描述

reactiveref 都可以定义对象类型的数据。监视对象中的某个属性时,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>

(三)解释

  1. 定义响应式对象:使用 reactive 定义 person,包含 nameagecar

  2. 修改对象属性:通过 changeNamechangeAgechangeCar1changeCar2changeCar 方法修改对象的属性。

如何在Vue 3 中的 watch:如何监视 reactiveref 定义的对象类型数据中的某个属性呢?

这就是重点了。

  1. 监视对象属性
  • 使用 watch 监视 person.nameperson.age,直接写成函数形式。

  • 使用 watch 监视 person.car,写成函数形式,并开启深度监视(deep: true)。这样既能监视car,又能监视car中的属性变化

(四)运行效果

  • 点击“修改名字”按钮,name 属性会变化,触发 watch

  • 点击“修改年龄”按钮,age 属性会变化,触发 watch

  • 点击“修改第一台车”和“修改第二台车”按钮,car 属性会变化,触发 watch

  • 点击“修改整个车”按钮,car 属性会整体变化,触发 watch


二、watch 的行为

(一)监视基本类型属性

监视对象中的基本类型属性(如 nameage)时,需要将属性包装成函数形式:

JavaScript复制

watch(() => person.name, (newValue, oldValue) => {
  console.log('name 变化了');
});

(二)监视对象类型属性

监视对象中的对象类型属性(如 car)时,可以直接写属性路径,但建议写成函数形式,并开启深度监视:

JavaScript复制

watch(() => person.car, (newValue, oldValue) => {
  console.log('car 变化了');
}, { deep: true });

(三)newValueoldValue

  • newValue:变化后的值。

  • oldValue:变化前的值。

  • 特殊情况:如果监视的是对象类型属性,newValueoldValue 会是同一个对象,除非整体替换对象。

(四)示例代码

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)。


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。