ready
论坛版主
论坛版主
  • UID24
  • 粉丝0
  • 关注0
  • 发帖数433
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:920回复:0

Vue3.0底层原理详解

楼主#
更多 发布于:2024-07-11 15:33

// 一)、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);
游客


返回顶部