乐趣区

关于vue.js:深入解读vue3-watch踩坑记录

间接上代码,总共测试了上面这些状况(看正文)

<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 属性 的形式才行。

退出移动版