
<template>
<divclass="watchDemo">
<h1>D:侦听响应式对象的属性</h1>
车队长姓名:{{ vehicleGroup.leaderName }}
<ul>
<li>车辆A:{{ vehicleGroup.vehicleA.driverName }},{{ vehicleGroup.vehicleA.carPlateNo }}</li>
<li>车辆B:{{ vehicleGroup.vehicleB.driverName }},{{ vehicleGroup.vehicleB.carPlateNo }}</li>
</ul>
<button @click="changeLeader">修改车队长</button>
<button @click="changeVehicleA">修改车A</button>
<button @click="changeVehicleB">修改车B</button>
<button @click="changeAllVehicle">修改车队</button>
</div>
</template>
<script lang='ts' setupname='WatchDemo'>
import{ reactive,watch } from 'vue'
let vehicleGroup = reactive({
leaderName:"车队长A",
vehicleA: {
driverName:"车A司机",
carPlateNo:"车A车牌号"
},
vehicleB: {
driverName:"车B司机",
carPlateNo:"车B车牌号"
}
})
function changeLeader() {
vehicleGroup.leaderName = vehicleGroup.leaderName + "+"
}
function changeVehicleA() {
vehicleGroup.vehicleA.carPlateNo = vehicleGroup.vehicleA.carPlateNo + "-"
vehicleGroup.vehicleA.driverName = vehicleGroup.vehicleA.driverName + "-"
}
function changeVehicleB() {
vehicleGroup.vehicleB.carPlateNo="车B车牌号~~new"
vehicleGroup.vehicleB.driverName="车B司机~~~~new"
}
function changeAllVehicle() {
vehicleGroup.vehicleA= {
driverName:"张师傅",
carPlateNo:"经A88888"
}
vehicleGroup.vehicleB= {
driverName:"李师傅",
carPlateNo:"齐C66666"
}
}
//侦听对象的基本类型
// watch(getLeaderName, (newVal, oldVal) => {
// console.log('车队长变了:', newVal, oldVal);
// })
// function getLeaderName(){
// return vehicleGroup.leaderName
// }
// 简单写法
watch(() =>vehicleGroup.leaderName,(newVal, oldVal) =>{
console.log('车队长变了:', newVal, oldVal);
})
// 侦听对象的对象
// 写法1,侦听属性对象。changeVehicleA可以侦听,changeAllVehicle无法侦听
// watch(vehicleGroup.vehicleA,(newVal,oldVal)=>{
// console.log('车A变了:', newVal, oldVal);
// })
// 写法2,侦听属性对象的getter函数。changeVehicleA无法侦听,changeAllVehicle可以侦听
// watch(()=>vehicleGroup.vehicleA,(newVal,oldVal)=>{
// console.log('车A变了:', newVal, oldVal);
// })
// 写法3,侦听属性对象的getter函数,并开启深度侦听。changeVehicleA、changeAllVehicle都可以侦听
watch(() =>vehicleGroup.vehicleA,(newVal, oldVal) =>{
console.log('车A变了:', newVal, oldVal);
}, {deep:true})
</script>
<style>
.watchDemo{
background-color: darkkhaki;
}
</style>如果侦听的属性是基本类型,按照 简单写法 即可。
如果侦听的属性是对象,按照 写法3,无论是修改对象的内部属性,还是修改整个对象,都能触发侦听。
watch数组&watchEffect
前文介绍的都是watch一个数据源,在实际的开发中,我们一般是侦听多个数据源,综合考虑进行逻辑处理,其方法如下:
<template>
<div class="watchEffectDemo">
<h1>Watch数组</h1>
姓名:<input type="text" v-model="jobSeeker.userName" required>
年龄:<select v-model="jobSeeker.age" required>
<option v-bind:value="0">请选择</option>
<option v-bind:value="34">34岁</option>
<option v-bind:value="35">35岁</option>
<option v-bind:value="36">36岁</option>
</select>
学历:<select v-model="jobSeeker.eduBg">
<option v-for="option in eduBgs" v-bind:value="option.value" required>
{{ option.text }}
</option>
</select>
</div>
</template>
<script lang='ts' setup name='WatchEffectDemo'>
import { reactive, watch } from 'vue'
let eduBgs = [
{ value: 0, text: "请选择" },
{ value: 1, text: "博士" },
{ value: 2, text: "硕士" },
{ value: 3, text: "本科" },
{ value: 99, text: "大专" }
]
let jobSeeker = reactive({ userName: "", eduBg: 0, age: 0 })
watch([() => jobSeeker.age, () => jobSeeker.eduBg], (newVal) => {
let [age, eduBg] = newVal
if (age === 0 || eduBg === 0) {
return
}
if (age < 35 && eduBg < 99) {
console.log('发送请求:', jobSeeker);
alert("真的已提交")
} else {
console.log('并没有提交', jobSeeker);
alert("已提交")
}
})
</script>
<style>
.watchEffectDemo {
background-color: lavender;
}
</style>与watch基本一致,只是数据源那里,变成了数组。
回调函数3个参数【新值、旧值、副作用清理回调函数】,后两个本节不需要,就没写。
与watch一个数据源一样,该注意的,watch多个数据源也一样注意,本节不赘述。
这样固然解决了watch多个数据源的需求,但在实际工作,watch的可能有N个数据源,全写在数组就很繁冗了,这就引入了watchEffect。
另外,在新版本的Vue中(我的是3.5.13),如果用watch侦听数组,控制台会提示:
watch(fn, options?)` signature has been moved to a separate API. Use `watchEffect(fn, options?)` instead. `watch` now only supports `watch(source, cb, options?) signature.
官方建议使用watchEffect来侦听多个数据源,改造如下:
watchEffect(() => {
if (jobSeeker.age === 0 || jobSeeker.eduBg === 0) {
return
}
if (jobSeeker.age < 35 && jobSeeker.eduBg < 99) {
console.log('发送请求:', jobSeeker);
alert("真的已提交")
} else {
console.log('并没有提交', jobSeeker);
alert("已提交")
}
})watchEffect不用像watch那样,指定要侦听的数据源,它会自动跟踪回调的响应式依赖。
watchEffect会立即执行一次回调函数,类似watch里的{immediate:true}。
watchEffect拿不到原值。










