阅读:908回复:0
Vue3.0底层原理详解// 一)、proxy和defineProperty的区别 1. proxy能代理数组 2. 兼容性 proxy ie11以上 defineProperty 兼容 ie8以上 3. proxy是代理,defineProperty是劫持 4. 配合Reflect,Reflect有13种方法,处理数据更灵活 // 二)、基本用法 let obj = { name: 'lilei' }; let proxy = new Proxy(obj, { // target目标对象,key 目标对象的key get(target, key) { return target[key]; }, //val 需要设置的值 set(target, key, val) { target[key] = val; } }); proxy.name = 1; // 三)、代理数据 实现更新 let obj = { name: "lilei", hobit: { one: "football", two: "eat" }, ary: [1, 2, 3, 4] }; function update() { console.log("更新"); } handle = { // target 目标对象,key 目标对象的key get(target, key) { // 判断target[key]是不是对象,如果是再返回劫持的对象(继续代理) if (typeof target[key] == "object" && typeof target[key] != null) { return new Proxy(target[key], handle); } return Reflect.get(target, key); // return target[key]; }, // val 需要设置的值 set(target, key, val) { // 因为数组的长度改变也会触发更新 if (key == "length") return true; update(); return Reflect.set(target, key, val); // target[key] = val; } }; let proxy = new Proxy(obj, handle); console.log(proxy); proxy.name = "lala"; proxy.hobit.one = "run"; proxy.ary.push(5); console.log(proxy); // 数组的更新会触发2次 // 数组触发更新触发两次是为什么 // 检测到length的改变 // 四)、参数使用 let obj = { name: 1 }; let handle = { // receiver 它总是指向原始的读操作所在的那个对象,一般情况下就是 Proxy 实例 get(target, key, receiver) { return receiver; }, set(target, key, val, receiver) { return Reflect.set(target, key, val, receiver); } }; let proxy = new Proxy(obj, handle); let res = proxy.getReceiver === proxy; console.log(res); // true // proxy和defineproper区别 // proxy可以代理数组,defineproperty只能代理对象 // pproxy性能好,没有的属性也可以进行双向绑定 // defineproperty兼容ie11,没有的属性不可以进行双向数据绑定 // proxy代理 let obj = { name: 1, age: { age: 1 } }; let arr = [1, 2, 3]; let handle = { get(target, key) { // 如果对象有多层,继续代理 if (typeof target[key] == "object" && typeof target[key] != null) { return new Proxy(target[key], handle); } return Reflect.get(target, key); // return target[key]; }, // 数组的更新会触发2次 set(target, key, value) { if (key == "length") return true; console.log("触发更新"); return Reflect.set(target, key, value); // return (target[key] = value); } }; let proxy = new Proxy(arr, handle); // 数组触发更新触发两次是为什么 // 检测到length的改变 proxy.push(1); // proxy.name = 123; console.log(proxy); // console.log(obj); |
|