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>
相关推荐
aha-凯心11 分钟前
vben 之 axios 封装
前端·javascript·学习
漫谈网络14 分钟前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
遗憾随她而去.25 分钟前
uniapp 中使用路由导航守卫,进行登录鉴权
前端·uni-app
xjt_090141 分钟前
浅析Web存储系统
前端
foxhuli2291 小时前
禁止ifrmare标签上的文件,实现自动下载功能,并且隐藏工具栏
前端
青皮桔2 小时前
CSS实现百分比水柱图
前端·css
失落的多巴胺2 小时前
使用deepseek制作“喝什么奶茶”随机抽签小网页
javascript·css·css3·html5
DataGear2 小时前
如何在DataGear 5.4.1 中快速制作SQL服务端分页的数据表格看板
javascript·数据库·sql·信息可视化·数据分析·echarts·数据可视化
影子信息2 小时前
vue 前端动态导入文件 import.meta.glob
前端·javascript·vue.js
青阳流月2 小时前
1.vue权衡的艺术
前端·vue.js·开源