You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Options API的watch中如何结构化对比嵌套对象的新旧值

解决方案

核心思路和Vue官方给出的Composition API实现逻辑完全一致:通过在监听源阶段对响应式对象做深拷贝,让watch内部存储的新旧值指向不同引用,即可实现结构化对比。以下提供3种可直接在Options API中使用的实现方案:


方案1:基于lodash的最简实现(官方推荐)

直接复用官方思路,在Options API中通过函数形式的监听源返回深拷贝结果:

import _ from 'lodash'

export default {
  // 其他组件配置省略
  data() {
    return {
      items: {
        // 你的深度嵌套对象数据
      }
    }
  },
  watch: {
    // 监听源为返回深拷贝items的函数
    [() => _.cloneDeep(this.items)]: {
      handler(newVal, oldVal) {
        // 直接用lodash内置深对比方法,也可替换为你自己实现的checkIfStructurallyEqual
        const isEqual = _.isEqual(newVal, oldVal)
        if (isEqual) return
        this.doSomething()
      },
      deep: true
    }
  }
}

方案2:无第三方依赖实现

如果不想引入lodash,可使用浏览器原生structuredClone做深拷贝,搭配你自己实现的深对比逻辑:

export default {
  data() {
    return {
      items: {
        // 嵌套数据
      }
    }
  },
  created() {
    // 手动注册watch,兼容性更强
    this.$watch(
      () => structuredClone(this.items),
      (newVal, oldVal) => {
        const isEqual = this.checkIfStructurallyEqual(newVal, oldVal)
        if (isEqual) return
        this.doSomething()
      },
      { deep: true }
    )
  },
  methods: {
    checkIfStructurallyEqual(obj1, obj2) {
      // 你已实现的深对比逻辑
    },
    doSomething() {
      // 业务逻辑
    }
  }
}

方案3:性能优化方案(适合超大对象场景)

如果你的嵌套对象数据量极大、深拷贝开销高,可手动维护旧值缓存,减少不必要的深拷贝次数:

import _ from 'lodash'

export default {
  data() {
    return {
      items: {
        // 大体积嵌套数据
      },
      // 存储上一次的深拷贝结果
      prevItemsCache: null
    }
  },
  watch: {
    items: {
      deep: true,
      handler(newVal) {
        // 首次加载时初始化缓存
        if (this.prevItemsCache === null) {
          this.prevItemsCache = _.cloneDeep(newVal)
          return
        }
        const isEqual = _.isEqual(newVal, this.prevItemsCache)
        if (!isEqual) {
          this.doSomething()
          // 逻辑执行完成后更新缓存
          this.prevItemsCache = _.cloneDeep(newVal)
        }
      }
    }
  }
}

注意事项
  • 深拷贝存在固定性能开销,如果对象包含函数、Symbol、DOM节点、Error实例等特殊类型,原生structuredClone无法正常拷贝,建议使用lodash.cloneDeep或者自定义深拷贝实现
  • 所有方案的deep: true配置不能省略,否则嵌套属性变更不会触发watch回调

内容的提问来源于stack exchange,提问作者deepanshMathur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:09:04