- 作用:监视数据的变化(和
Vue2
中的watch
作用一致) - 特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。- 一个包含上述内容的数组。
我们在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
定义的对象中的属性,newValue
和oldValue
都是新值,因为它们是同一个对象。- 若修改整个
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定义的对象类型中某一个属性
监视ref
或reactive
定义的【对象类型】数据中的某个属性,注意点如下:
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
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>