vue3 watch与watchEffect

watch

单个变量监听

监听ref属性
const theName = ref('张三')
watch(theName, newVal => {
  console.log('newVal', newVal)
})
监听reactive属性
监听单个属性
const obj = reactive({
  name: '张三',
  hobby: [
    {
      title: '你好',
    },
  ],
})

watch(
  () => obj.name,
  newVal => {
    console.log(newVal)
  }
)
监听整个reactive对象
const obj = reactive({
  name: '里斯',
  hobby: [
    {
      title: '你好',
    },
  ],
})
watch(obj, (newObj, oldObj) => {
  // 此处的newObj与oldObj实际是同一个,也就是说,直接监听整个reactive对象,无法正确获取到oldObj
  console.log(toRaw(newObj))
  console.log(toRaw(oldObj))
})
进一步测试
<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">点我+1</button>
  <hr />
  <h2>当前的信息为:{{ msg }}</h2>
  <button @click="msg += ''">修改信息</button>
  <hr />
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>薪资:{{ person.job.j1.salary }}K</h2>
  <button @click="person.name += '~'">修改姓名</button>
  <button @click="person.age++">增长年龄</button>
  <button @click="person.job.j1.salary++">涨薪</button>
</template>

<script>
import { ref, reactive, watch } from "vue";
export default {
  name: "Demo",
  setup() {
    //数据
    let sum = ref(0);
    let msg = ref("你好啊");
    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 3,
        },
      },
    });

    //情况一:监视ref所定义的一个响应式数据
    watch(
      sum,
      (newValue, oldValue) => {
        console.log("sum变了", newValue, oldValue);
      },
      { immediate: true }
    );

    //情况二:监视ref所定义的多个响应式数据
    watch(
      [sum, msg],
      (newValue, oldValue) => {
        console.log("sum或msg变了", newValue, oldValue);
      },
      { immediate: true }
    );

    /* 
    情况三:监视reactive所定义的一个响应式数据的全部属性
        1.注意:此处无法正确的获取oldValue
        2.注意:强制开启了深度监视(deep配置无效)
    */
    watch(
      person,
      (newValue, oldValue) => {
        console.log("person变化了", newValue, oldValue);
      },
      { deep: false }
    ); //此处的deep配置无效

    //情况四:监视reactive所定义的一个响应式数据中的某个属性
    // watch(
    //   () => person.name,
    //   (newValue, oldValue) => {
    //     console.log("person的name变化了", newValue, oldValue);
    //   }
    // );

    //情况五:监视reactive所定义的一个响应式数据中的某些属性
    // watch([() => person.name, () => person.age], (newValue, oldValue) => {
    //   console.log("person的name或age变化了", newValue, oldValue);
    // });

    //特殊情况
    // watch(
    //   () => person.job,
    //   (newValue, oldValue) => {
    //     console.log("person的job变化了", newValue, oldValue);
    //   },
    //   { deep: true }
    // ); //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效

    //返回一个对象(常用)
    return {
      sum,
      msg,
      person,
    };
  },
};
</script>
总结
  • 如果定义了reactive的数据,想去使用watch监听数据改变,则无法正确获取旧值,并且deep属性配置无效,自动强制开启了深层次监听。
  • 如果使用 ref 初始化一个对象或者数组类型的数据,会被自动转成reactive的实现方式,生成proxy代理对象。也会变得无法正确取旧值。
  • 用任何方式生成的数据,如果接收的变量是一个proxy代理对象,就都会导致watch这个对象时,watch回调里无法正确获取旧值。
  • 所以当大家使用watch监听对象时,如果在不需要使用旧值的情况,可以正常监听对象没关系;但是如果当监听改变函数里面需要用到旧值时,只能监听 对象.xxx属性 的方式才行。

多个变量监听

const theName = ref('张三')
const obj = reactive({
  name: '里斯',
  hobby: [
    {
      title: '你好',
    },
  ],
})
watch(
  [theName, () => obj.name],
  ([newTheName, newName], [oldTheName, oldName]) => {
    console.log('new', newTheName, ' , ', newName)
    console.log('old', oldTheName, ' , ', oldName)
  }
)

watchEffect

vue3中你不知道的watch和watchEffect 侦听器
浅谈Vue3的watchEffect用途

参考

深入解读vue3 watch(踩坑记录)!

官方: watch说明

vue3中你不知道的watch和watchEffect 侦听器

浅谈Vue3的watchEffect用途

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值