# 响应式原理

# Vue2.x实现

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

TIP

  • 存在问题:新增属性(新增响应式数据)、删除属性, 界面不会更新。 -备注:可以通过$set$delete解决
  • 直接通过下标修改数组, 界面不会自动更新。 -备注:可以通过$set或者splice替换的方法解决

# Vue3.x实现

proxy:是ES6一个新增特性。Proxy有两个参数一个是原始的对象 一个是用来定制拦截的行为(捕获器)。

  • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等
  • 通过Reflect(反射): 对源对象的属性进行操作。
new Proxy(data, {
    // 拦截读取属性值
    get (target, prop) {  // target:源对象 prop:某个属性名
        return Reflect.get(target, prop)
    },
    // 拦截修改属性值或添加新属性
    set (target, prop, value) {
        return Reflect.set(target, prop, value)
    },
    // 拦截删除属性
    deleteProperty (target, prop) {
        return Reflect.deleteProperty(target, prop)
    }
})

为什么要使用Reflect而不直接使用target[prop]?

Reflect会有一个返回值true或false,如果成功返回true,失败返回false,这样在底层编写代码的时候减少try,catch的使用。

Last Updated: 2/21/2023, 4:16:42 PM