对一个存储了多个对象的数组实现watch监听

需求分析

在vue中,我们使用watch很容易就能实现对一个变量的监听,同样,一个数组,一个对象也都不难实现,但是实际项目中可能会出现更为复杂的情况。比如说,一个存储了多个对象的数组。我们现在要去监听这个数组里面每一个对象的某个属性。如下代码,leaveData里面每一个对象的startDate属性,我们要做的就是监听这个属性,当其变化时,执行方法watchHandler

leaveData:[
    {
      startDate:'',//开始日期
      startPart:'am',//开始时间段
      endDate:'',//结束日期
      endPart:'pm',//结束时间段
      leaveTypeVal:[],//请假类型
      calendarDay:'',//日历天数
      workDay:'',//工作天数
    },
    {
      startDate:'',//开始日期
      startPart:'am',//开始时间段
      endDate:'',//结束日期
      endPart:'pm',//结束时间段
      leaveTypeVal:[],//请假类型
      calendarDay:'',//日历天数
      workDay:'',//工作天数
    },
],//请假事项数组

初步实现代码

leaveData: {
        handler(newValue, oldValue) {
          for (let i = 0; i < newValue.length; i++) {
            if (oldValue[i].startDate != newValue[i].startDate) {
              this.watchHandler(i);
              break;
            }
          }
        },
        immediate: false,
        deep: true,
},
  1. handler为leaveDate变化时执行的方法
  2. newValue,oldValue为变化后的值和变化前的值
  3. immediate:如果为true 意味着一进入页面就会立即先去执行handler方法,false则不执行
  4. deep 深层监听,对一个对象内部的属性进行深层监听需要令其为true

出现的问题和解决方案

我们在使用上述代码进行监听之后会发现,newValue和oldValue是一样的。
解决方案:将我们需要的值在computed中进行序列化和反序列化,但是在页面的dom结构中仍然使用原有的leaveData进行数据绑定,不能使用leaveDataNew,否则会出现如下拉框无法选择值的状况。

最终实现代码

...
<div v-for="(item,index) in leaveData" :key="index">
....
</div>
...


computed: {
  	leaveDataNew() {
        return JSON.parse(JSON.stringify(this.leaveData))//watch监听要求
  	},
 },
 
watch: {
  leaveDataNew: {
    handler(newValue, oldValue) {
      for (let i = 0; i < newValue.length; i++) {
        if (oldValue[i].startDate != newValue[i].startDate) {
          this.watchHandler(i);
          break;
        }
      }
    },
    immediate: false,
    deep: true,
  },
},
Logo

前往低代码交流专区

更多推荐