Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?

Posted

技术标签:

【中文标题】Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?【英文标题】:Vue: Do watchers on deep nested objects log oldVal and newVal? 【发布时间】:2021-05-31 11:34:26 【问题描述】:

我在深层嵌套对象上有一个watcher。我正在使用Vue.set() 向对象添加反应属性。这触发了观察者,但 newVal 和 oldVal 控制台日志都显示了已经添加了新属性的数据,而不是 oldVal 显示了在添加新属性之前它是什么

  <button @click="addData">Add</button>


  data() 
    return 
      myData: 
        time: 

        
      
    
  ,
  watch: 
    myData: 
      handler(newVal, oldVal) 
        console.log("NEW", newVal);
        console.log("OLD", oldVal);
      ,
      deep: true
    
  ,
  methods: 
    addData() 
      this.$set(this.myData.time, 'other','testing')
    
  

【问题讨论】:

这能回答你的问题吗? Vuejs get old value when on change event API 文档中提到你不能:VueJS 不保留对对象前值的引用:vuejs.org/v2/api/#vm-watch 这能回答你的问题吗? Vue watch array push same old and new values 【参考方案1】:

正如@Terry 所说,vue 不保留对oldValue 的引用,看看docs 是怎么说的:

注意:当改变(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。 Vue 不保留预突变值的副本。


有一些方法可以解决这个问题:

使用原生 javascript

添加一个计算属性,将您的数据属性转换为JSON string。 在 Watch 函数上使用 JSON.parse 将字符串转换回对象。
data() 
  return 
    myData: 
      time: 

      
    
  
,
computed: 
  computedMyData() 
    return JSON.stringify(this.myData);
  
,
watch: 
  computedMyData: 
    handler(newValJSON, oldValJSON) 
      let newVal = JSON.parse(newValJSON),
          oldVal = JSON.parse(oldValJSON);
      
        console.log("NEW", newVal);
        console.log("OLD", oldVal);
      ,
      deep: true
    
  ,
methods: 
  addData() 
    this.$set(this.myData.time, 'other','testing')
  


小提琴:https://jsfiddle.net/mLbuf6t0/

使用LODASH

使用cloneDeep 函数添加一个计算属性,该属性从您的数据属性返回一个深度克隆。
data() 
  return 
    myData: 
      time: 

      
    
  
,
computed: 
  computedMyData() 
    return _.cloneDeep(this.myData)
  
,
watch: 
  computedMyData: 
    handler(newVal, oldVal)             
      console.log("NEW", newVal);
      console.log("OLD", oldVal);
    ,
    deep: true
  
,
methods: 
  addData() 
    this.$set(this.myData.time, 'other','testing')
  

小提琴:https://jsfiddle.net/mLbuf6t0/2/

【讨论】:

以上是关于Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 观察深层属性

无法过滤表中使用 Vue 计算的深层数组对象

vue 提供注入 provideinject 深层嵌套通信

谈谈 Vue shallowRef 和 shallowReactive

vue、watch功能对Array和Object的监听oldVal,val新老值一样的解决方案

chart接入后台数据后vue不响应式显示图片