您现在的位置是:首页 >学无止境 >vue3学习四 watch网站首页学无止境

vue3学习四 watch

A黄俊辉A 2024-06-14 17:17:43
简介vue3学习四 watch

在vue3中使用watch 来监听某个数据的变化, 因为我们定义数据的时候有 ref 和 reactive 两种方法, 所以watch 也会分出不同的五种情况

当使用 watch 来监听 ref 定义的数据时

<template>
  <div> sum: {{sum}}</div>
  <button @click="sum++">sum变化</button>
  <div> msg: {{msg}}</div>
  <button @click="msg+='!'">msg 变化</button>
</template>

<script>
import {ref,reactive,watch} from "vue";
export default {
  name: 'App',
  setup(){
    let sum = ref(0);
    let msg = ref("你好啊");
    // watch(sum,(newvalue,oldvalue)=>{
    //   console.log("sum发生了变化",newvalue,oldvalue);
    // })
    //两个变量一起监听
    watch([sum,msg],(newvalue,oldvalue)=>{
      console.log(newvalue); //此时的 newvalue 是一个数组
      console.log(oldvalue); //此时的 oldvalue 是一个数组
    })
    return {
      sum,
      msg
    }
  },
}
</script>

从上面的代码中, 我们可以看到, 如果我们只监听一个数据的时候可以使用

watch(sum,(newvalue,oldvalue)=>{
	//逻辑代码
},{immediate:true})

如果我们要监听两个或多个数据, 最简单的方法就是 多写一个 watch 就可以了
还可以使用 数组的方式

    watch([sum,msg],(newvalue,oldvalue)=>{
      console.log(newvalue); //此时的 newvalue 是一个数组
      console.log(oldvalue); //此时的 oldvalue 是一个数组
    },{immediate:true})

当我们使用 watch 去监听一个 reactive定义的数据

<template>
  <div>person:{{person}}</div>
  <button @click="person.name+='!'">person name改变</button>
  <br/>
  <button @click="person.age+=1">person age改变</button>
  <br/>
  <button @click="person.job.j1.salary++">person job j1 salary 改变</button>
  <br/>
  <button @click="person.job.j2.salary++">person job j2 salary 改变</button>
</template>

<script>
import {ref,reactive,watch} from "vue";
export default {
  name: 'App',
  setup(){
    let person = reactive({
      name:"黄哥",
      age:38,
      job:{
        j1:{
          salary:20
        },
        j2:{
          salary:50
        }
      }
    })

    watch(person,(newvalue,oldvalue)=>{
      console.log("发现了person发生了变化",newvalue,oldvalue)
    },{immediate:true,deep:false})

    watch(()=>person.age,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
    })

    watch([()=>person.name,()=>person.age],(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
    })

    watch(()=>person.job,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue);
    },{deep:true})

    watch(()=>person.job.j1.salary,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
    })


    return {
      person
    }
  },
}
</script>

从上面的代码我们可以分现多种情况

情况一 整体监听 person 对象

watch(person,(newvalue,oldvalue)=>{
      console.log("发现了person发生了变化",newvalue,oldvalue)
    },{immediate:true,deep:false})

这里的 person 强制开启了 deep:true , 上面虽然配置了 deep:false, 但是是没有用的,同时还有一个小bug , 这里只能得到 newvalue, oldvalue 是得不到了, 如果实在需要 oldvalue 的话, 可以对每个属性单独监听

情况二 监听其中的某一个属性

    watch(()=>person.age,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
    })

watch 的第一个参数有三种形式, 第一种, ref或reactive 定义的数据, 第二种, 可以是一个数组,第三种, 也可以是一个回调函数
所以, 这里如果 写成 watch(person.age,…) 这种写法是错误的
正确的写法是 watch(()=>return person.age,…) 简化的写法就是 watch(()=> person.age)

情况三,监听多个属性,这里要使用 回调函数加数组的方式了

    watch([()=>person.name,()=>person.age],(newvalue,oldvalue)=>{
     console.log(newvalue,oldvalue)
   })

其原因和情况二差不多, 不用多说了

情况四 如果监听 person , 是默认强制开启的 {deep:true},配不配deep都是一样的;但如果监听的是 person 内部的对象数据的时候, 是可以使用 deep 来配置的

    watch(()=>person.job,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue);
    },{deep:true})

在这里插入图片描述
上面的代码中, 我们更改的是 person.job.j1.salary 发生改变, 但是这里监听的是 person.job, 所以如果我们不配置 deep:true, 则是不可以监听到数据变化的

情况五

    watch(()=>person.job.j1.salary,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
    })

这种和情况二是差不多的。只不过是更深层的数据

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。