Proxy 实现原理
Vue2.x 实现响应式数据的原理
对象 类型数据的处理
使用数据劫持的方式,通过 Object.defineProperty( )对属性的读取、修改进行拦截
this.$set(this.a, "b", 2); //对象新增属性 Vue.set(this.a, "b", 2); this.$delete(this.a, "b"); //对象删除属性 Vue.delete(this.a, "b");
数组 类型数据的处理
通过重写数组的 7 个方法( push、pop、shift、unshift、splice、reverse、sort ),拦截对数组的修改,实现响应式数据
this.$set(this.b, 0, "xxx"); //将数组索引为0的数据修改为 xxx Vue.set(this.b, 0, "xxx");
缺点
- 新增属性、删除属性时,页面不会更新( $set , $delect )
- 直接通过数组下标修改数据时,页面不会更新
实现
Object.defineProperty(data, "a", { get() {}, //捕获数据读取时 set() {}, //捕获修改数据时 });
Vue3.x 实现响应式数据的原理
let a = { a: 1, b: 2, }; //创建Proxy实例对象,a 为源数据 const p = new Proxy(a, {});
- 当修改 Proxy 实例对象时
p.a = 3; // a.a = 3
修改代理对象时,源数据内部数据也会同步修改
修改包含对数据的新增、修改、删除
- 捕获数据的修改
const p = new Proxy( a , { get ( target , propName ) { //target 为源数据,此处为 a //propName 为当前读取的属性名 此处可为 a、b //返回值为读取时获取的值 return target[propName] }, set ( target , propName , value ) { //target 为源数据,此处为 a //propName 为当前读取的属性名,此处可为 a、b //value 为修改属性时赋予的新值 //将修改时的新值赋予给需要修改的属性 target[propName] = value } deleteProperty ( target , propName ) { //target 同上 //propName 同上 //返回值为删除属性时外部接受到的值 return delete target[propName] } } )
- 读取数据时:使用 get 函数
- 修改数据时:使用 set 函数
- 删除数据时:使用 deleteProperty 函数
- 新增数据时:使用 set 函数
Reflect 反射属性
//修改属性 Reflect.set(a, "b", 4); //读取属性 Reflect.get(a, "b"); //删除属性 Reflect.deleteProperty(a, "b");
通过反射属性,对对象进行数据的操作
- Reflect 反射属性包含 Object 的方法和属性
const b = Reflect.defineProperty(a, "c", 5); // true const c = Reflect.defineProperty(a, "c", 6); // false
当代码有错误时,Reflect 通过返回值确定代码执行结果
不抛出错误,中断程序执行
可以避免使用 try... catch... 进行错误的捕获