废话不多说,直接上代码。。。。。。。。。。。
<template>
<div class="person">
<div>数字等于<span>{{num}}</span></div>
<div>
<span>{{person.name}}</span>
<span>{{person.age}}</span>
</div>
<div>
<span>{{car.name}}</span>
<span>{{car.type}}</span>
</div>
</div>
<footer>
<button @click="changeNums">修改数字</button>
<button @click="changeName">修改姓名</button>
<button @click="changeAge">修改年龄</button>
<button @click="changePerson">修改人员</button>
<button @click="changeCarName">修改汽车品牌</button>
<button @click="changeCar">修改汽车</button>
<button @click="changeCarType">修改汽车类型</button>
<button @click="changeCarPrice">修改汽车类型</button>
</footer>
</template>
<script lang="ts" setup name='person'>
import { reactive, ref, watch } from 'vue';
// vue3 watch监听的5种情况
// 1.监听ref定义的【基本类型】
let num = ref(0)
function changeNums(){
num.value++
}
watch(num,(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
//2.监听ref定义的【对象类型】
let person = ref({
name:'zhangsan',
age:18
})
function changeName(){
person.value.name = 'lisi'
}
function changeAge(){
person.value.age ++
}
function changePerson(){
person.value = {'name':'王五','age':90}
}
// 这种写法只能监听到内部属性变化changePerson的时候无法监听
// watch(person.value,(newVal,oldVal)=>{
// console.log('zz1',newVal,oldVal)
// })
// 监听person变化 deep后监听内部属性变化
watch(person,(newVal,oldVal)=>{
console.log('zz2',newVal,oldVal)
},{deep:true})
//3.监听reactive定义的【对象类型】 默认开启深度监听
let car = reactive({
name:'奥迪',
type:'Q3',
price:[{'type1':30},{'type2':25}]
})
function changeCarName(){
car.name += '~'
}
function changeCar(){
// Object.assign(car,{name:'小米',type:'su7',price:[{'type1':25},{'type2':35}]})
}
watch(car,(newValue,oldValue)=>{
console.log('zz3',newValue,oldValue)
})
// 4.监视`ref`或`reactive`定义的【对象类型】数据中的**某个属性** 函数式
function changeCarType(){
car.type = 'Q5'
}
watch(()=>car.type,(newVal,oldVal)=>{
console.log('zz4',newVal,oldVal)
})
// 5.监视多个属性,使用数组
function changeCarPrice(){
car.price[0].type1 = 99
}
watch([()=>car.name,car.price],(newVal,oldVal)=>{
console.log('zz5',newVal,oldVal)
},{deep:true})
</script>
<style lang="less" scoped>
.person{
background: silver;
width: 600px;
height: 300px;
div{
margin: 10px;
}
}
</style>
注意,在使用watch时,控制台打印newvalue和oldvalue时候会出现一致的情况。这是因为操作的响应式对象只是发生属性变化,没有全部改变,重新指向新地址,watch在监听时候打印时,value值已经变成newvalue。如果想打印前后变化的值,可以使用computed配合JSON.stringify解决该问题。
let car = reactive({
name:'奥迪',
type:'Q3',
price:[{'type1':30},{'type2':25}]
})
let newcar = computed(() => {
return JSON.stringify(car );
});
如上只要监听newcar,控制台oldvalue和newvalue打印即可不同。