Vue2可以检测 引用数据类型 数组的响应式变化

发布时间 2023-03-23 15:57:45作者: .李宁宁
在Vue2中,响应式基于Object.defineProperty实现的响应式,官方文档中明确说明

Vue 不能检测以下数组的变动:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

并不是Object.defineProperty不具备检测数组的能力,而是因为性能问题,Vue2放弃了使用Object.defineProperty来监听数组的响应式,而是尤大团队实现了垫片,具体来说:Vue2修改了数组原型方法,例如:push、pop、shift、splice等,这些方法对数组的操作是可以被监听到的
但是我在工作中,碰到了一个特别的情况,也实现了数组下标修改数据实现响应式,具体代码如下:

// 模版中的代码如下:
<div>
  {{ array }}
</div>
<div>
  <button @click="add">增</button>
  <button @click="del">删</button>
  <button @click="update">改</button>
  <button @click="query">查</button>
</div>

// script代码
data() {
    return {
      array: [{ flog: false }],
    }        
}
methods: {
  add() {
    this.array.push({ flog: true })
  },
  del() {
    this.array.pop()
  },
  update() {
    this.array[0].flog = !this.array[0].flog
  },
  query() {
    console.log(this.array)
  },
}

操作结果:add、del、update 都实现了响应式,驱动了试图的更新
遗留:我不理解,为什么update实现了响应式,我通过下标的方式,修改了数组的数据,却实现了响应式

而对于原始数据类型的数组,检测不到变化(合理),下边是一个例子:

// 模版中的代码如下:
<div>
  {{ array }}
</div>
<div>
  <button @click="add">增</button>
  <button @click="del">删</button>
  <button @click="update">改</button>
  <button @click="query">查</button>
</div>

// script代码
data() {
    return {
      array: [1, 2, 3, 4, 5],
    }        
}
methods: {
  add() {
    this.array.push(6)
  },
  del() {
    this.array.pop()
  },
  update() {
    this.array[0] = 99
  },
  query() {
    console.log(this.array)
  },
}

操作结果:add、del都生效,可以触发响应式,而update不能触发响应式,我通过console.log输出了array,可以看到array[0]的数据变为了 99