【Vue3】watch监听的五种情况
学习来源:尚硅谷
- 作用:监视数据的变化(和
Vue2
中的watch
作用一致) - 特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。reactive
定义的数据。- 函数返回一个值(
getter
函数)。- 一个包含上述内容的数组。
在vue3中,如果我们要定义响应式数据,可以采用ref和reactive声明定义变量,我们在Vue3
中使用watch
的时候,通常会遇到以下几种情况:
1、※※※ 监听ref定义的基本类型数据
监视ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
<script setup>
/**
* 监视`ref`定义的【基本类型】数据:直接写数据名即可,监视的是其`value`值的改变。
*/
import { ref, watch } from 'vue'
let num = ref(1)
function updateNum() {
num.value++
}
watch(num, (vul) => {
console.log('num变化了:', vul)
})
</script>
<template>
<h1>
{{ num }}
</h1>
<button @click="updateNum">num+1</button>
</template>
2、监听ref定义的对象类型数据
监视ref
定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
注意:
-
若修改的是
ref
定义的对象中的属性,newValue
和oldValue
都是新值,因为它们是同一个对象。 -
若修改整个
ref
定义的对象,newValue
是新值,oldValue
是旧值,因为不是同一个对象了。
<script setup>
/**
* 监视`ref`定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
*/
import { ref, watch } from 'vue'
let person = ref({
name: 'zs',
age: 13
})
function updateName(){
person.value.name += '~'
}
function updatePerson() {
person.value = {
name: 'ls',
age: 18
}
}
watch(person, (vul) => {
console.log('person变化了', vul)
}, {
deep: true
})
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
</template>
3、监听reactive定义的对象类型数据
当然了,reactive也不能定义基本类型数据,
监视reactive
定义的【对象类型】数据,且默认开启了深度监视,并且是不可关闭的深度监听。数据中的任何一点蛛丝马迹的变化,都会被监听到。
<script setup>
// 监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。
import { reactive, watch } from 'vue'
let person = reactive({
name: 'zs',
age: 18,
car: {
c1: 'c1',
c2: 'c2'
}
})
function updateName() {
person.name += '~'
}
function updatePerson() {
person = Object.assign(person, {
name: 'lisi',
age: 13
})
}
function updateCar() {
person.car.c1 += '1'
}
watch(person, (vul) => {
console.log('person变化了', vul)
})
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<h1>car: {{ person.car.c1 + '--' + person.car.c2 }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
<button @click="updateCar">修改car</button>
</template>
4、※※※ 监听ref或reactive定义的数据中的某个属性 ※
监视ref
或reactive
定义的【对象类型】数据中的某个属性,注意点如下:
- 若该属性值不是【对象类型】,需要写成函数形式。
- 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
<script setup>
// 监视`reactive`定义的【对象类型】数据,且默认开启了深度监视。
import { reactive, watch } from 'vue'
let person = reactive({
name: 'zs',
age: 18,
car: {
c1: 'c1',
c2: 'c2'
}
})
function updateName() {
person.name += '~'
}
function updatePerson() {
person = Object.assign(person, {
name: 'lisi',
age: 13
})
}
function updateCar() {
person.car.c1 += '1'
}
watch(() => person.name, (vul) => {
console.log('person.name变化了', vul)
})
watch(() => person.car, (vul) => {
console.log('person.car变化了', vul)
}, {
deep: true
})
</script>
<template>
<h1>姓名: {{ person.name }}</h1>
<h1>年龄: {{ person.age }}</h1>
<h1>car: {{ person.car.c1 + '--' + person.car.c2 }}</h1>
<button @click="updateName">修改姓名</button>
<button @click="updatePerson">修改整个人</button>
<button @click="updateCar">修改car</button>
</template>
5、组合监听多个数据
组合监听多个数据,使用数组进行包裹
<template>
<h1>sum: {{ sum }}</h1>
<h1>name: {{ person.name }}</h1>
<button @click="updateSum">修改sum</button>
<button @click="updateName">修改name</button>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue'
let sum = ref(0)
let person = reactive({
name: 'zs'
})
function updateName() {
person.name += '~'
}
function updateSum() {
sum.value += 1
}
watch([sum, person], (newVal) => {
console.log('数据变化了:', newVal)
})
</script>