<template>
<div>
<p>count1: {{ count1 }} -- count2: {{ count2 }}</p>
<button @click="addCount1">count1+1</button>
<button @click="multiplyCount2">count2 * 2</button>
</div>
-----------
<div>
<div>姓名: {{ person.name }}</div>
<div>年龄: {{ person.age }}</div><br>
<div>车辆信息<br>
<div>品牌: {{ person.car.brand }}</div>
<div>颜色: {{ person.car.type.color }}</div>
<div v-if="person && person.car">配置:
<ul>
<li v-for="config in person.car.type.configs" :key="config">{{ config }}</li>
</ul>
</div>
</div>
<button @click="addAge">age+1</button>
<button @click="changeBrand">changeBrand</button>
<button @click="changeColor">changeColor</button>
<button @click="addConfigs">addConfigs</button>
</div>
</template>
<script>
import { reactive, ref, watch, watchEffect } from 'vue';
export default {
name: 'WatchCom',
setup() {
const count1 = ref(0)
const count2 = ref(1)
const addCount1 = () => {
count1.value++
}
const multiplyCount2 = () => {
count2.value *= 2
}
// 1.侦听ref数据(单个)
// 注意:1)直接侦听count1,不用.value 2)newVal、oldVal正常
watch(count1, (newVal, oldVal) => {
console.log('新count', newVal);
console.log('旧count', oldVal);
})
// 2.侦听ref数据(多个)
// 注意:1)以数组形式作为参数 2)newVal、oldVal正常
watch([count1, count2], (newVal, oldVal) => {
console.log('新数组', newVal);
console.log('旧数组', oldVal);
})
// ---------------------------------------
const person = reactive({
name: 'zs',
age: 18,
car: {
brand: 'benz',
type: {
color: 'red',
configs: ['天窗', '倒车影像', '座椅加热']
}
}
})
const addAge = () => {
person.age++
}
const changeBrand = () => {
person.car.brand += '!'
}
const changeColor = () => {
person.car.type.color += '#'
}
const addConfigs = () => {
person.car.type.configs.push('新配置')
}
// 3.侦听reactive数据
// 3.1直接侦听reactive对象
// 注意:1)直接将reactive作为侦听参数,侦听器会自动启用深层模式
// 2)若以函数形式侦听reactive对象,则要开启深度侦听,否则侦听无效
// 3)newVal正常,但oldVal异常(指向同一个对象)
// 写法1
// watch(person, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// })
// 写法2
// watch(() => person, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// }, { deep: true })
// 3.2侦听reactive对象中的某个属性(简单数据类型)
// 注意:1)需要以函数形式作为参数,只侦听当前数据(深层不会侦听)
// 2)newVal、oldVal正常
// watch(() => person.age, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// })
// 3.3侦听reactive对象中的某个属性(引用数据类型/复杂数据类型)
// 注意:1)需要以函数形式作为参数
// 2)需要开启深层侦听{ deep: true }
// 3)newVal正常,但oldVal异常(指向同一个对象)
// watch(() => person.car, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// }, { deep: true })
// 3.4侦听reactive对象中的某个属性(引用数据类型/复杂数据类型)的属性(简单数据类型)
// 注意:1)需要以函数形式作为参数
// 2)newVal、oldVal正常
// watch(() => person.car.brand, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// })
// 3.5侦听reactive对象中的某个属性(引用数据类型/复杂数据类型)的属性(引用数据类型)
// 注意:1)需要以函数形式作为参数
// 2)需要开启深层侦听{ deep: true }
// 3)newVal正常,但oldVal异常(指向同一个对象)
// watch(() => person.car.type, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// }, { deep: true })
// 3.6侦听reactive对象中的某个属性(引用数据类型/复杂数据类型)的属性(引用数据类型)的属性(简单数据类型)
// 注意:1)需要以函数形式作为参数
// 2)newVal、oldVal正常
// watch(() => person.car.type.color, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// })
// 3.5侦听reactive对象中的某个属性(引用数据类型/复杂数据类型)的属性(引用数据类型)的属性(引用数据类型)
// 注意:1)需要以函数形式作为参数
// 2)需要开启深层侦听{ deep: true }
// 3)newVal正常,但oldVal异常(指向同一个对象)
// watch(() => person.car.type.configs, (newVal, oldVal) => {
// console.log('新', newVal);
// console.log('旧', oldVal);
// }, { deep: true })
// 总结:
// 1.直接侦听reactive对象,默认开启深度侦听
// 2.侦听简单数据类型,不需要深度侦听;侦听引用数据类型,需要深度侦听
// 3.深度侦听需要遍历侦听对象中所有嵌套属性,当用于大型数据结构时,开销很大,谨慎使用
// 4.watchEffect
// watchEffect(立即执行的回调函数, options?)
// 用途:只要是在回调函数中出现的变量,就会侦听(简单数据类型才有效!!!!!)
watchEffect(() => {
console.log(person.age); // 有效
console.log(person.car);
console.log(person.car.brand); // 有效
console.log(person.car.type);
console.log(person.car.type.color); // 有效
console.log(person.car.type.configs);
})
// 5.回调的触发时机:默认情况下,watch/watchEffect的回调函数是在Vue组件更新前被调用
// 意味着,在回调中访问的DOM是更新前的状态
// 若想在回调中访问更新后的DOM,配置 { flush:'post' }
watch(source, callback,{ flush:'post' })
// watchEffect有两种写法:
// 第一种:
watchEffect(callback,{ flush:'post' })
// 第二种:
import { watchPostEffect } from 'vue'
watchPostEffect(()=>{
/* 在 Vue 更新后执行 */
})
return { count1, count2, addCount1, multiplyCount2, person, addAge, changeBrand, changeColor, addConfigs }
}
}
</script>
Vue3 watch和watchEffect
于 2022-08-23 00:12:59 首次发布