JS之监听对象属性的变化并获取变化的属性

JS实现监听对象属性的变化并获取变化的属性:

原代码:

watch(
  () => formData.value,
  (newVal, oldVal) => {
    for (const key in newVal) {
      if (newVal[key] !== oldVal[key]) {
        console.log(
          `Changed property: ${key}, Old value: ${oldVal[key]}, New value: ${newVal[key]}`
        );
      }
    }
  },
  { deep: true }
);

获取的旧值和新值一样

新代码:

import _ from "lodash";

let previousFormData = _.cloneDeep(formData.value);

watch(
  () => formData.value,
  (newVal) => {
    for (const key in newVal) {
      if (newVal[key] !== previousFormData[key]) {
        console.log(
          `Changed property: ${key}, Old value: ${previousFormData[key]}, New value: ${newVal[key]}`
        );
      }
    }
    previousFormData = _.cloneDeep(newVal);
  },
  { deep: true }
);

代码解释

1.手动缓存旧值:在 watch 外部声明一个变量 previousFormData,并在初始化时对 formData.value 进行深拷贝赋值给它。

2.监听回调函数:在 watch 的回调函数里,直接使用 previousFormData 与新值 newVal 进行对比,找出发生变化的属性并输出信息。

3.更新旧值缓存:在对比完成后,将 newVal 深拷贝给 previousFormData,以便下一次变化时能正确对比。

4.参数 { deep: true } 表明要进行深度监听。

 

2025-09-19更新:

若newVal[key]是数组,会因为引用值不同,而判断失败,可优化为

let previousFormData = _.cloneDeep(formData.value);
watch(
  () => formData.value,
  (newVal) => {
    for (const key in newVal) {
      const oldVal = previousFormData[key];
      const newValItem = newVal[key];
      let hasChanged = false;

      // 判断值是否发生变化
      if (Array.isArray(newValItem) && Array.isArray(oldVal)) {
        hasChanged =
          newValItem.length !== oldVal.length ||
          newValItem.join(",") !== oldVal.join(",");
      } else {
        hasChanged = newValItem !== oldVal;
      }

      if (hasChanged) {
        console.log(`Changed property: ${key}`);
        console.log(`  Old value: ${JSON.stringify(oldVal)}`);
        console.log(`  New value: ${JSON.stringify(newValItem)}`);
        // do stuff
      }
    }
    previousFormData = _.cloneDeep(newVal);
  },
  { deep: true }
);

 

posted @ 2025-04-07 10:19  罗毅豪  阅读(137)  评论(0)    收藏  举报