vue3:7、组合式API-watch和watchEffect

目录

watch 

情况一:监视【ref】定义的【基本类型】数据

 情况二:监视【ref】定义的【对象类型】数据

情况三:监视【reactive】定义的【对象类型】数据 , 默认开启了深度监视。

情况四: 监视ref或reactive定义的【对象类型】数据中的某个属性

情况五: 监视上述多个数据


watch 

作用:监视数据的变化(和vue2中的watch作用一致)

特点:vue3中的watch只能监视以下四种数据

1、ref定义的数据

2、reactive定义的数据

3、函数返回一个值(getter函数)。

4、一个包含上述内容的数组。

我们在Vue3中使用watch的时候,通常会遇到以下几种情况:

情况一:监视【ref】定义的【基本类型】数据

监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。 

<script setup lang="ts">
import {ref,watch} from 'vue'
let sum = ref(0)

function changeSum(){
  sum.value++
}
//监视
let stopwatch = watch(sum,(newVal,oldVal)=>{
  console.log('sum变化了',newVal,oldVal)
  if(newVal>=10){
    stopwatch()//停止监视
  }
})

console.log(stopwatch)
/**
 * () => {
    effect2.stop();
    if (scope) {
      remove(scope.effects, effect2);
    }
  }
 */
</script>

<template>
  <h1>情况一:监视【ref】定义的基本类型数据</h1>
 <div class="">
  <h2>当前求和为{{ sum }}</h2>
  <button @click="changeSum">点我sum+1</button>
 </div>
</template>

<style scoped>

</style>

 情况二:监视【ref】定义的【对象类型】数据

监视的是对象的地址值。若想监视对象内部属性的变化,需要手动开启deep属性

  1. watch的第一个参数是:被监视的数据
  2. watch的第二个参数是:监视的回调
  3. watch的第三个参数是:配置对象(deep,immediate等等...)

注意:

  • 若修改的是ref定义的对象中的属性,newVal和oldVal都是新值,因为他们是同一个对象
  • 若修改整个ref定义的对象,newVal是新值,oldVal是旧值,因为不是同一个对象了 
<script setup lang="ts">
import {ref,watch} from 'vue'
let person = ref({
  name:"张三",
  age:18
})
function changePersonName(){
  person.value.name+='&'
  //watch的时候,newVal和oldVal相等,都是新的perosn.name的值
}
function changePersonAge(){
  person.value.age+=1
  //watch的时候,newVal和oldVal相等,都是新的perosn.age的值
}
function changePerson(){
  // person.value.name+='&'
  // person.value.age+=1
  person.value = {
    name:"1",
    age:2
  }
  //watch的时候,newVal和oldVal不相等,newVal是person的新值,old是person的旧值
}
//监视
/**
 * 监视的是对象的地址值,
 * 若想监视对象内部属性的变化,需要手动开启deep属性
 */
let stopwatch = watch(person,(newVal,oldVal)=>{
  console.log('变化了',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
},{deep:true})

console.log(stopwatch)
/**
 * () => {
    effect2.stop();
    if (scope) {
      remove(scope.effects, effect2);
    }
  }
 */
</script>

<template>
  <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
 <div class="">
  <h2>姓名:{{person.name}}</h2>
  <h2>姓名:{{person.age}}</h2>
  <button @click="changePersonName">点我改name</button>
  <button @click="changePersonAge">点我改age</button>
  <button @click="changePerson">点我改所有</button>
 </div>
</template>

<style scoped>

</style>

情况三:监视【reactive】定义的【对象类型】数据 , 默认开启了深度监视。

function changePerson(){
  //reactive修饰的对象,不可整体修改
  // person = {
  //   name:"1",
  //   age:2
  // }
  
  
  //ref修饰的对象【 person.value = .. 】是重新给对象赋制,对象的地址已经发生变化了。
  //reactive修饰的对象,做以下操作时是批量修改person的属性。对象的地址没有发生变化。
  Object.assign(person,{name:"hei",age:100})
}

<script setup lang="ts">
import {reactive,watch} from 'vue'
let person = reactive({
  name:"张三",
  age:18
})
function changePersonName(){
  person.name+='&'
}
function changePersonAge(){
  person.age+=1
}
function changePerson(){
  //reactive修饰的对象,不可整体修改
  // person = {
  //   name:"1",
  //   age:2
  // }
  
  //ref修饰的对象【 person.value = .. 】是重新给对象赋制,对象的地址已经发生变化了。
  //reactive修饰的对象,做以下操作时是批量修改person的属性。对象的地址没有发生变化。
  Object.assign(person,{name:"hei",age:100})
}
//监视
watch(person,(newVal,oldVal)=>{
  console.log('变化了',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
})

</script>

<template>
  <h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
 <div class="">
  <h2>姓名:{{person.name}}</h2>
  <h2>姓名:{{person.age}}</h2>
  <button @click="changePersonName">点我改name</button>
  <button @click="changePersonAge">点我改age</button>
  <button @click="changePerson">点我改所有</button>
 </div>
</template>

<style scoped>

</style>

情况四: 监视ref或reactive定义的【对象类型】数据中的某个属性

注意:

  • 若该属性值不是【对象类型】,需要写成函数形式。
  • 若该属性值依然是【对象类型】,可以直接编,也可以写成函数,不过建议写成函数
  • 若该属性值依然是【对象类型】,监视的是地址值,若是需要关注对象内部,需要手动开启深度监视
<script setup lang="ts">
import {reactive,watch} from 'vue'
let person = reactive({
  name:"张三",
  age:18,
  car:{
    c1:"比亚迪",
    c2:"宝马",
  }
})
function changePersonName(){
  person.name+='&'
}
function changePersonAge(){
  person.age+=1
}
function changeC1(){
  person.car.c1 = '特斯拉'
}
function changeC2(){
  person.car.c2 = '劳斯莱斯'
}
function changeCar(){
  person.car = {
    c1:"小米汽车",
    c2:"QQ飞车"
  }
}
//监视name:监视响应式对象中的某个属性。且该属性是基本类型的,要写成函数式
watch(()=>{return person.name},(newVal,oldVal)=>{
  console.log('name变化了',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
})
//监视age
watch(()=>person.age,(newVal,oldVal)=>{
  console.log('age变化了',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
})
//监视person.car对象【点击“changeCar”按钮,watch监听不到,怎么解决?写成函数式】
// watch(person.car,(newVal,oldVal)=>{
//   console.log('person.car',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
// })
//监视car:监视响应式对象中的某个属性。且该属性是对象类型的,可以直接写,也能写函数,更推荐写成函数式
watch(()=>{return person.car},(newVal,oldVal)=>{
  console.log('person.car',newVal,oldVal) //变化了 Proxy(Object) {name: '1', age: 2} Proxy(Object) {name: '1', age: 2}
},{deep:true})//手动开启deep

</script>

<template>
  <h1>情况四:监视ref或reactive定义的【对象类型】数据中的某个属性</h1>
 <div class="">
  <h2>姓名:{{person.name}}</h2>
  <h2>姓名:{{person.age}}</h2>
  <h2>汽车{{person.car.c1}}</h2>
  <h2>汽车{{person.car.c2}}</h2>
  <button @click="changePersonName">点我改name</button>
  <button @click="changePersonAge">点我改age</button>
  <button @click="changeC1">修改第一台车</button>
  <button @click="changeC2">修改第二台车</button>
  <button @click="changeCar">修改整个车</button>
 </div>
</template>

<style scoped>

</style>

情况五: 监视上述多个数据

第一种,值也用数组

第一种,值不用数组 

<script setup lang="ts">
import {reactive,watch} from 'vue'
let person = reactive({
  name:"张三",
  age:18,
  car:{
    c1:"比亚迪",
    c2:"宝马",
  }
})
function changePersonName(){
  person.name+='&'
}

function changeC1(){
  person.car.c1 = '特斯拉'
}
//监视上述多个数据
watch([()=>{return person.name},()=>{return person.car.c1}],(newVal,oldVal)=>{
  console.log('变化了',newVal,oldVal) 
})

</script>

<template>
  <h1>情况五:监视上述多个数据</h1>
 <div class="">
  <h2>姓名:{{person.name}}</h2>
  <h2>姓名:{{person.age}}</h2>
  <h2>汽车{{person.car.c1}}</h2>
  <h2>汽车{{person.car.c2}}</h2>
  <button @click="changePersonName">点我改name</button>
  <button @click="changeC1">修改第一台车</button>

 </div>
</template>

<style scoped>

</style>

watchEffect

官网:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。

watch对比watchEffect

  • 都能监听响应式数据的变化,不同的是监听数据变化的方式不同
  • watch:要明确指出监视的数据
  • watchEffect:不同明确指出监视的数据(函数中用到哪些水性,那就监视哪些属性)。
<script setup lang="ts">
import {ref,watch,watchEffect} from 'vue'
let temp = ref(10)
let height = ref(0)
function changeTemp(){
  temp.value+=10
}
function changeHeight(){
  height.value+=1
}
//监视
// let stopwatch = watch(sum,(newVal,oldVal)=>{
//   console.log('sum变化了',newVal,oldVal)
//   if(newVal>=10){
//     stopwatch()//停止监视
//   }
// })
watch([temp,height],([t,h])=>{
  console.log(t,h)
  // let [t,h] = newVal
  if(t>=60||h>=10){
    console.log('ok')
  }
})

//当temp和height变化的时候,就会触发
watchEffect(()=>{
   if(temp.value>=60||height.value>=10){
    console.log('ok')
  }
})
</script>

<template>
 <div class="">
  <h2>当水温达到60度,或水位达到10米,发送请求</h2>
  <h2>当前水温:{{ temp }}℃</h2>
  <h2>当前水位:{{ height }}米</h2>
  <button @click="changeTemp">水温+10</button>
  <button @click="changeHeight">高度+1</button>
 </div>
</template>

<style scoped>

</style>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值