vue3+ts的watch全解!

vue3中的watch只能监听以下四种数据:

1.ref定义的数据

2.reactive定义的数据

3.函数返回一个值(getter函数)

4.一个包含上述内容的数组

通常我们在使用watch的时候,通常会遇到以下几种情况:

情况一:

监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。

我们首先写一个watch,这里面要传两个值,一个是监视的字段,还有一个是回调函数,里面返回两个值newValue, oldValue,看下面的截图就知道啦~一个是变化前,一个是变化后!

超过10就会解除监视

复制代码
<template>
  <div class="person">
    <h1>情况一:监视【ref】数据【基本类型】数据</h1>
    <h2>当前求和为:{{ sum }}</h2>
    <button @click="changeSum">点我sum+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { ref, watch } from "vue";
let sum = ref(0);
0;
function changeSum() {
  sum.value += 1;
}
const stopWatch = watch(sum, (newValue, oldValue) => {
  console.log("sum变化了");
  console.log(newValue, oldValue);
  if (newValue > 10) {
    stopWatch();
  }
});
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>

情况二:

监视ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。

复制代码
<template>
  <div class="person">
    <h1>情况二:监视ref定义的【对象类型】数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { ref, watch } from "vue";
let person = ref({
  name: "张三",
  age: 19,
});
function changeName() {
  person.value.name += "~";
}
function changeAge() {
  person.value.age += 1;
}
function changePerson() {
  person.value = { name: "李四", age: 40 };
}
// 监视的是对象的地址值!若想监视对象内部属性的变化,需要手动开启深度监视!
watch(
  person,
  (newValue, oldValue) => {
    console.log("person变化了", newValue, oldValue);
  },
  { deep: true }
);
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>

这里补充一下:

若修改的是ref定义对象中的属性,则newValue和oldValue都是新值,因为他们都是同一个对象

若修改的是整个ref定义的对象,则newValue是新值oldValue是旧值,因为不是同一个对象了

watch有三个参数了,第一个是监视的数据,第二个是监视的回调,第三个是配置对象!

情况三:

监视reactive定义的【对象类型】数据,且默认开启了深度监视!

复制代码
<template>
  <div class="person">
    <h1>情况三:监视reactive定义的【对象类型】数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from "vue";
let person = reactive({
  name: "张三",
  age: 19,
});
function changeName() {
  person.name += "~";
}
function changeAge() {
  person.age += 1;
}
function changePerson() {
  Object.assign(person, { name: "李四", age: 40 });
}
// 监视reactive定义的对象类型数据,且默认是开启深度监视的!
watch(person, (newValue, oldValue) => {
  console.log("person变化了", newValue, oldValue);
});
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>

这种会隐式的创建深度监听!而且关不掉!!!

情况四:

监视ref或reactive定义的【对象类型】数据中的某个属性 注意点如下:

1.若该属性不是【对象类型】,需要写成函数形式。

2.若该属性值是依然是【对象类型】,可直接编辑,也可写成函数,不过建议写成函数。

我现在定义了一个reactive的数据对象,然后我想监视这个对象里面的属性,这个就得用一个箭头函数去支撑!才可以做到

复制代码
<template>
  <div class="person">
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeCar">修改第一台车</button>
    <button @click="changeCar2">修改第二台车</button>
    <button @click="changeCar3">修改整个car</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from "vue";
let person = reactive({
  name: "张三",
  age: 19,
  car: {
    c1: "奔驰",
    c2: "宝马",
  },
});

function changeName() {
  person.name += "~";
}
function changeAge() {
  person.age += 1;
}
function changeCar() {
  person.car.c1 += "~";
}
function changeCar2() {
  person.car.c2 += "~";
}
function changeCar3() {
  person.car = {
    c1: "雅迪",
    c2: "爱玛",
  };
}

watch(
  () => person.name,
  (newValue, oldValue) => {
    console.log("person变化了", newValue, oldValue);
  }
);
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>

只要想监视对象中的某个属性,就直接写函数就完了!然后如果你想关注内部的值,就直接deep:true

复制代码
<template>
  <div class="person">
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeCar">修改第一台车</button>
    <button @click="changeCar2">修改第二台车</button>
    <button @click="changeCar3">修改整个car</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from "vue";
let person = reactive({
  name: "张三",
  age: 19,
  car: {
    c1: "奔驰",
    c2: "宝马",
  },
});

function changeName() {
  person.name += "~";
}
function changeAge() {
  person.age += 1;
}
function changeCar() {
  person.car.c1 += "~";
}
function changeCar2() {
  person.car.c2 += "~";
}
function changeCar3() {
  person.car = {
    c1: "雅迪",
    c2: "爱玛",
  };
}

// watch(
//   () => person.name,
//   (newValue, oldValue) => {
//     console.log("person变化了", newValue, oldValue);
//   }
// );
watch(
  () => person.car,
  (newValue, oldValue) => {
    console.log("person变化了", newValue, oldValue);
  },
  { deep: true }
);
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>

情况五:

监视上述多个数据,用一个数组包含一下,然后写函数即可

复制代码
<template>
  <div class="person">
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}{{ person.car.c2 }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeCar">修改第一台车</button>
    <button @click="changeCar2">修改第二台车</button>
    <button @click="changeCar3">修改整个car</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive, watch } from "vue";
let person = reactive({
  name: "张三",
  age: 19,
  car: {
    c1: "奔驰",
    c2: "宝马",
  },
});

function changeName() {
  person.name += "~";
}
function changeAge() {
  person.age += 1;
}
function changeCar() {
  person.car.c1 += "~";
}
function changeCar2() {
  person.car.c2 += "~";
}
function changeCar3() {
  person.car = {
    c1: "雅迪",
    c2: "爱玛",
  };
}

watch([() => person.name, () => person.car.c1], (newValue, oldValue) => {
  console.log("person变化了", newValue, oldValue);
});
</script>

<style scoped>
.person {
  background-color: #ddd;
  box-shadow: 0 0 10px;
  border-radius: 10px;
  padding: 20px;
}
</style>
相关推荐
WooaiJava1 小时前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
LYFlied1 小时前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
爱喝白开水a1 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied1 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌411 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
B站_计算机毕业设计之家1 小时前
豆瓣电影数据采集分析推荐系统 | Python Vue Flask框架 LSTM Echarts多技术融合开发 毕业设计源码 计算机
vue.js·python·机器学习·flask·echarts·lstm·推荐算法
WeiXiao_Hyy2 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡2 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone2 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09013 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js