0


Vue2中给对象添加新属性界面不刷新

Vue2中给对象添加新属性界面不刷新?

Vue2.x的响应式

实现原理

  • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。
  • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
Object.defineProperty(data, 'count', {
    get () {}, 
    set () {}
})

存在问题

  • 新增属性、删除属性, 界面不会更新。
  • 直接通过下标修改数组, 界面不会自动更新。

解决方案

  • 使用Vue.setVue.delete或者vm.$setvm.$delete这些API

模拟vue2的响应式

//源数据
let person = {
    name:'张三',
    age:18
}
//模拟Vue2中实现响应式
let p = {}
Object.defineProperty(p,'name',{
    configurable:true,
    get(){ //有人读取name时调用
        return person.name
    },
    set(value){ //有人修改name时调用
        console.log('有人修改了name属性,我发现了,我要去更新界面!')
        person.name = value
    }
})
Object.defineProperty(p,'age',{
    get(){ //有人读取age时调用
        return person.age
    },
    set(value){ //有人修改age时调用
        console.log('有人修改了age属性,我发现了,我要去更新界面!')
        person.age = value
    }
})

vue3的响应式

结论

在vue3中已经不存在上述的问题了

实现原理

  • 通过 Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
  • 通过Reflect(反射): 对源对象的属性进行操作。
let person = {
    name:'YK菌',
    age:18
}

const p = new Proxy(person,{
    //有人读取p的某个属性时调用
    get(target,propName){
        console.log(`有人读取了p身上的${propName}属性`)
       // return target[propName]
        return Reflect.get(target,propName)
    },
    //有人修改p的某个属性、或给p追加某个属性时调用
    set(target,propName,value){
        console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`)
        // target[propName] = value
        return Reflect.set(target,propName,value)
    },
    //有人删除p的某个属性时调用
    deleteProperty(target,propName){
        console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`)
        // return delete target[propName]
       return Reflect.deleteProperty(target,propName)
    }
})

为什么要使用Reflect,ECMA正在把Object上的方法转移到Reflect上面去

因为要让框架变得更加健壮,所以需要捕获错误,要不然一发生错误就运行不了了
利用Object.defineProperty捕获错误需要使用trycatch,不易读
在这里插入图片描述

而使用Reflect,因为Reflect会有返回值,直接使用if判断就可以捕获错误了
在这里插入图片描述


本文转载自: https://blog.csdn.net/weixin_50975172/article/details/130931686
版权归原作者 kyydmby 所有, 如有侵权,请联系我们删除。

“Vue2中给对象添加新属性界面不刷新”的评论:

还没有评论