vue监听数据时 newValue, oldValue操作处理

要只存入新更改的数据,可以在 watch 的回调函数中进行比较,筛选出有变化的属性并将其存入新数组。以下是一个示例代码,假设要监听的对象为 obj:

data() {
  return {
    differenceArray: [], 
    obj: { /* 对象的初始属性 */ }
  };
},
computed:{
  newObj(){
    return JSON.parse(JSON.stringify(this.obj)); 
  }
},
watch:{
  newObj:{
    handler(newValue, oldValue){
      const changedProperties = Object.entries(newValue).filter(([key, value]) => value!== oldValue[key]); 
      this.differenceArray.push(...changedProperties.map(([key, value]) => ({ key, value }))); 
    },
    deep:true
  }
}

在上述代码中,使用 Object.entries() 获取对象的所有属性键值对。通过 filter() 方法筛选出在新值和旧值中不相等的属性。然后,使用 map() 方法将这些变化的属性转换为包含 key(属性名)和 value(新更改后的值)的对象,并使用扩展运算符 … 将这些对象添加到 differenceArray 数组中。
这样,differenceArray 数组中就只会存储实际发生更改的属性及其新值。
如果监听的是数组,可以类似地进行处理。例如,对于数组 arr:

data() {
  return {
    differenceArray: [], 
    arr: [ /* 数组的初始元素 */ ]
  };
},
computed:{
  newArr(){
    return [...this.arr]; 
  }
},
watch:{
  newArr:{
    handler(newValue, oldValue){
      const changedIndices = newValue.reduce((indices, value, index) => {
        if (value!== oldValue[index]) {
          indices.push(index); 
        }
        return indices;
      }, []); 
      changedIndices.forEach(index => {
        this.differenceArray.push({ index, value: newValue[index] }); 
      });
    },
    deep:true
  }
}

在这个示例中,通过遍历新数组和旧数组,找出值不相同的索引位置,并将这些索引存到 changedIndices 数组中。然后,遍历 changedIndices,将对应的索引和新值作为对象添加到 differenceArray 数组中。

要解决 newVal 和 oldVal 一样的问题,并将新更改的数据存入 differenceArray 数组,可以使用 Vue 的 watch 选项中的 deep: true 来深度监听对象的变化。以下是修改后的代码示例:

watch: {
  newEditTableVariables: {
    handler(newValue, oldValue) {
      this.differenceArray = []; 
      // 遍历 newValue 中的每个项目
      newValue.forEach(item => {
        // 在 oldValue 中找到对应的项目
        const oldItem = oldValue.find(idx => idx.value === item.value); 
        // 如果没有找到对应的旧项目,或者找到的旧项目与新项目不同,则将新项目添加到 differenceArray 中
        if (!oldItem || JSON.stringify(oldItem)!== JSON.stringify(item)) { 
          this.differenceArray.push(item);
        }
      });
      console.log(this.differenceArray);
    },
    deep: true, // 深度监听对象内部属性的变化
    immediate: true // 立即执行 handler 函数
  }
}

在上述代码中,使用 JSON.stringify() 来比较新旧项目是否全等。通过深度监听,当 newEditTableVariables 对象内部的属性发生变化时,handler 函数会被触发。然后,通过遍历 newValue 并与 oldValue 进行比较,将有差异的项目添加到 differenceArray 数组中。
注意,直接修改对象的属性可能无法触发响应式更新,导致 watch 监听不到变化。如果 newEditTableVariables 是一个复杂的对象,确保在对象内部属性发生变化时,使用 Vue 提供的方法(例如 Vue.set() 或数组的变异方法)来进行修改,以确保响应式系统能够正确检测到变化。另外,添加 immediate: true 是为了在初始化时立即执行一次 handler 函数,以便获取初始值和后续变化的比较。
如果 newEditTableVariables 是一个数组,并且你使用了一些可能导致 Vue 无法检测到数组变化的方式(例如直接通过索引修改数组元素),则需要使用 Vue 提供的数组变异方法,如 splice() 等,来确保变化能够被正确监听。例如:

this.$set(this.newEditTableVariables, index, newValue); 
// 或使用 splice 方法
this.newEditTableVariables.splice(index, 1, newValue); 
watch: {
  newEditTableVariables: {
    handler(newValue, oldValue) {
      this.differenceArray = []; 
      // 遍历 newValue 中的每个项目
      newValue.forEach(item => {
        // 在 oldValue 中找到对应的项目
        const oldItem = oldValue.find(idx => idx.value === item.value); 
        // 如果没有找到对应的旧项目,或者找到的旧项目与新项目不同,则将新项目添加到 differenceArray 中
        if (!oldItem || JSON.stringify(oldItem)!== JSON.stringify(item)) { 
          this.differenceArray.push(item);
        }
      });
      console.log(this.differenceArray);
    },
    deep: true, // 深度监听对象内部属性的变化
    immediate: true // 立即执行 handler 函数
  }
} 

这段代码是 Vue 中 watch 选项的使用示例,用于监听 newEditTableVariables 对象的变化。
以下是对代码的详细解释:
watch:Vue 提供的用于监听数据变化的选项。
newEditTableVariables:要监听的数据源。
handler(newValue, oldValue):当数据源发生变化时触发的回调函数。接收两个参数:newValue 表示变化后的新值,oldValue 表示变化前的旧值。
在回调函数内部:
this.differenceArray = []:初始化一个空数组 differenceArray,用于存储变化的差异数据。
通过 newValue.forEach(item => {…}) 遍历 newValue 中的每个项目。
在内部的嵌套循环中,使用 oldValue.find(idx => idx.value === item.value) 在 oldValue 中查找与当前 item 的 value 属性相等的项目,并将其赋值给 oldItem。
通过条件判断 if (!oldItem || JSON.stringify(oldItem)!== JSON.stringify(item)) 来检查是否没有找到对应的旧项目,或者找到的旧项目与新项目不相等(使用 JSON.stringify 进行序列化比较)。如果满足条件,说明有差异,就将当前项目 item 使用 this.differenceArray.push(item) 添加到 differenceArray 数组中。
deep: true:表示进行深度监听。当 newEditTableVariables 是一个复杂的嵌套对象时,启用深度监听可以确保对象内部属性的变化也能被监听到。
immediate: true:表示立即执行 handler 函数。即使在初始化时,newEditTableVariables 的值没有发生变化,也会立即执行一次 handler 函数,将初始值作为 oldValue 传入,方便进行一些初始的处理或比较。
总体来说,这段代码的目的是在 newEditTableVariables 对象发生变化时,找出变化的差异部分并存储在 differenceArray 数组中,以便后续使用或处理这些差异数据。通过深度监听和立即执行的设置,能够更全面地捕捉和处理对象的变化情况。
如果你发现这段代码中存在“无用的数据”,可能是指在实际使用中,newEditTableVariables 对象中的某些数据或属性并不是你真正关心的差异部分。要解决这个问题,你可以根据具体的业务需求,进一步优化差异比较的逻辑。例如,只比较特定的属性、或者针对特定类型的数据进行特殊处理等。
例如,如果你只想比较对象中某些特定属性的变化,可以修改比较条件:

if (!oldItem || oldItem.specificProperty!== item.specificProperty) { 
  this.differenceArray.push(item);
}

其中 specificProperty 替换为你实际想要比较的属性名。
或者,如果对象中的数据结构比较复杂,可能需要根据具体情况设计更复杂的差异比较算法,以准确获取你所需的差异数据。

以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!

  • 32
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小纯洁w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值