Vue3开发极简入门:watchEffect

www.jswusn.com Other 2025-06-03 09:55:41 8次浏览

侦听响应式对象的某个属性(使用getter函数)


一个响应式对象,如果内容比较多,层级比较深,全侦听的话,很耗资源。实际开发中,通常只需要侦听内部几个属性即可。


<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拿不到原值。


上一篇:没有了!

Other

下一篇:uni-app如何自定义页面的title

技术分享

苏南名片

  • 联系人:吴经理
  • 电话:152-1887-1916
  • 邮箱:message@jswusn.com
  • 地址:江苏省苏州市相城区

热门文章

Copyright © 2018-2025 jswusn.com 版权所有

技术支持:苏州网站建设  苏ICP备18036849号