Vue3 watch 监视属性

  • 作用:监视数据的变化(和Vue2中的watch作用一致)
  • 特点:Vue3中的watch只能监视以下四种数据
  1. ref定义的数据。
  2. reactive定义的数据。
  3. 函数返回一个值(getter函数)。
  4. 一个包含上述内容的数组。

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

ref定义的基本类型

vue 复制代码
<template>
  <div class="person">
    <h2>当前求和{{ sum }}</h2>
    <button @click="changeAddOne">点击加一</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect } from 'vue'

// 数据
let sum = ref(0);

// 方法
function changeAddOne() {
  sum.value++;
}

// 监视 watch(谁,回调函数)
watch(sum, (newValue, oldValue) => {
  console.log('sum发生变化了', newValue, oldValue);
});
</script>

watch监视里面的ref数据不需要.value

主动停止监视:

vue 复制代码
<template>
  <div class="person">
    <h2>当前求和{{ sum }}</h2>
    <button @click="changeAddOne">点击加一</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect } from 'vue'

// 数据
let sum = ref(0);

// 方法
function changeAddOne() {
  sum.value++;
}

// 监视 watch(谁,回调函数)
const stopWatch = watch(sum, (newValue, oldValue) => {
  console.log('sum发生变化了', newValue, oldValue);
  if(newValue >= 10) {
    stopWatch();
  }
});
</script>

ref定义的对象数据

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

注意:

  • 若修改的是ref定义的对象中的属性,newValueoldValue 都是新值,因为它们是同一个对象。
  • 若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了。
vue 复制代码
<template>
  <div class="person">
    <h2>Person</h2>
    <p>姓名:{{ person.name }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeAge">年龄+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect } from 'vue'

// 数据
let person = ref({
  name: '张三',
  age: 18
});
// 方法
function changeAge() {
  person.value.age++;
}

// 监视 watch(谁,回调函数)
// 监视的是对象的地址值,若想监视对象内部的属性,需要手动开启深度监视 - deep: true
watch(person, (newVal, oldVal) => {
  console.log('watch:', newVal, oldVal);
}, {deep: true, immediate: true});
</script>

watch的参数:

  • 第一个参数:被监视的数据
  • 第二个参数:监视的回调
  • 第三个监视:配置对象(deep, imediate)

reactive定义的对象数据

reactive默认监视开启深度监视。

vue 复制代码
<template>
  <div class="person">
    <h2>Person</h2>
    <p>姓名:{{ person.name }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeAge">年龄+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect, reactive } from 'vue'

// 数据
let person = reactive({
  name: '张三',
  age: 18
});
// 方法
function changeAge() {
  person.age++;
}

// 监视 watch(谁,回调函数)
// 默认开始深度监视 
watch(person, (newVal, oldVal) => {
  console.log('watch:', newVal, oldVal);
}, {immediate: true});
</script>

监视ref/reactive定义的对象类型中某一个属性

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

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

结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。

vue 复制代码
<template>
  <div class="person">
    <h2>Person</h2>
    <p>姓名:{{ person.name }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeAge">年龄+1</button>
    <p>车:{{ person.car.c1 }}</p>
    <button @click="changeCarC1">修改第一量车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect, reactive } from 'vue'

// 数据
let person = reactive({
  name: '张三',
  age: 18,
  car:{
    c1:'宝马',
    c2:'奔驰'
  }
});
// 方法
function changeAge() {
  person.age++;
}
function changeCarC1() {
  person.car.c1 += '---';
}
// 监视 watch(谁,回调函数)
// 默认开始深度监视 
watch(() => {
  return person.age
}, (newVal, oldVal) => {
  console.log('age:', newVal, oldVal);
});
</script>
vue 复制代码
<template>
  <div class="person">
    <h2>Person</h2>
    <p>姓名:{{ person.name }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeAge">年龄+1</button>
    <p>车:{{ person.car.c1 }}</p>
    <button @click="changeCarC1">修改第一量车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect, reactive } from 'vue'

// 数据
let person = reactive({
  name: '张三',
  age: 18,
  car:{
    c1:'宝马',
    c2:'奔驰'
  }
});
// 方法
function changeAge() {
  person.age++;
}
function changeCarC1() {
  person.car.c1 += '---';
}
// 监视 watch(谁,回调函数)
// 默认开始深度监视 
watch(() => {
  return person.car
}, (newVal, oldVal) => {
  console.log('car:', newVal, oldVal);
}, {deep:true});
</script>

多个数据?

vue 复制代码
<template>
  <div class="person">
    <h2>Person</h2>
    <p>姓名:{{ person.name }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeAge">年龄+1</button>
    <p>车:{{ person.car.c1 }}</p>
    <button @click="changeCarC1">修改第一量车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { computed,watch, ref, watchEffect, reactive } from 'vue'

// 数据
let person = reactive({
  name: '张三',
  age: 18,
  car:{
    c1:'宝马',
    c2:'奔驰'
  }
});
// 方法
function changeAge() {
  person.age++;
}
function changeCarC1() {
  person.car.c1 += '---';
}
// 监视 watch(谁,回调函数)
// 默认开始深度监视 
watch(() => {
  return [person.car, person.age]
}, (newVal, oldVal) => {
  console.log('car:', newVal, oldVal);
}, {deep:true});
</script>
相关推荐
红烧小肥杨4 分钟前
javaWeb项目-Springboot+vue-车辆管理系统功能介绍
java·前端·vue.js·spring boot·后端·mysql·毕业设计
开心工作室_kaic8 分钟前
高校心理教育辅导设计与实现(论文+源码)_kaic
javascript·vue.js·spring boot
weixin_4432906919 分钟前
【快速上手】使用 Vite 来创建一个 Vue 3项目
前端·javascript·vue.js
前端wchen23 分钟前
知识篇:(八)微前端架构:从零开始搭建 qiankun 并运行不同的子项目
前端·react.js·架构
customer0824 分钟前
【开源免费】基于SpringBoot+Vue.JS音乐分享平台(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
customer0829 分钟前
【开源免费】基于SpringBoot+Vue.JS渔具租赁系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源
半糖112240 分钟前
前端数据拷贝(浅拷贝、深拷贝)
前端
前端小芬芬42 分钟前
element-plus 官方表格排序问题
前端·javascript·vue.js·elementui
xxxxxmy1 小时前
Django的模板语法
java·javascript·后端·pycharm·django
哟哟耶耶1 小时前
css-背景图片全屏显示适配不同尺寸覆盖
前端·css