你不知道的~响应式数据

126 阅读2分钟

​携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

1.v2中哪些情况操作数据不是响应式的?

常见的有以下三种情况

1.给对象后续新增的key进行赋值

data() {

    return {

         obj:{ }

     } }

后续添加 this.obj.age = 18 给age赋值不是响应式的

2.删除对象中的某一项

data(){

    return {

        obj:{

           age:18

        }

     }

}

delete this.obj.age

3.通过索引去修改数组的元素

data() {

    return {

       arr: ['a','b','c']

     }

}

this.arr[0] = 'd'

2.为什么这些情况不是响应式的?

1.给对象后续新增的key进行赋值

原因:

因为在v2中双向绑定原理是通过Object.defineProperty递归劫持对象中的每一个属性,如果这个属性是后续被添加的,当然就没有劫持到 , 一上来就对对象里面已有的数据进行递归劫持,后续添加的属性没有劫持到

2.删除对象中的某一项

原因

Object.defineProperty不支持对删除操作的劫持

3.通过索引去修改数组的元素

原因

并不是Object.defineProperty不支持对数组的劫持,而是作者出于对性能的原因没有这样做,因为数组里面的内容有很多很多项,对数组的性能不是很好,

3.怎么解决?

1.给对象后续新增的key进行赋值

解决:Vue.set() 或this.$set()

Vue.set(this.obj,'age',18) 也可以换为this.$set

2.删除对象中的某一项

解决:Vue.delete() 或this.$delete()

Vue.delete(this.obj,'age')

3.通过索引去修改数组的元素

解决: Vue.set() 或 this.$set() 或 arr.splice()

Vue.set(this.arr,0,'d')

变更方法 arr.splice(0,1,'d')

4.Vue3呢? 

Vue3不存在上述问题

1.给对象后续新增的key进行赋值

Vue3响应式的原理换成了Proxy,可以直接代理整个对象,v2代理的是整个对象的属性, 就无所谓这个属性是不是后续添加的了

2.删除对象中的某一项

Proxy支持对删除操作 2的拦截

3.通过索引去修改数组的元素

Proxy对数组的操作不存在性能问题