• Vue3.0 响应式reactive的原理实现


    代码如下

    index.js

    // 这里定义一个Symbol 是为了 当我们的新建的Proxy相应, result2又从新执行这个响应,
    就返回之前的响应 九月渲染性能
    //const result1 = reactive(value);
    //const result2 = reactive(result1);
    const IS_REACTIVE = Symbol("is_reactive");
    
    // 判断 是否是一个对象
    function isObject(target) {
        const result = Object.prototype.toString.call(target);
        if(result == '[object Object]'|| result == '[object Array]') {
            return true;
        }
        return false;
    }
    
    // 这个 创建一个WeakMap 来存放 以前如果创建过 proxy的话, 就那它的之前的缓存值
    // key 只能为对象, WeakMap 跟Map是差不多的,区别是WeakMap 是弱引用,就是值没用的时候 会自动进行垃圾回收机制,节约性能 Map则续收手动的清除
    const reactMap = new WeakMap();
    
    function reactive(target) {
      // 首先 判断 target 是不是对象
      if(!isObject(target)) {
        return;
      }
    
      // 这里的作用是 如果已经是一个 reactive了, 那么再reactive 就没必要了,就从新返回之前的目标值
      if(target[IS_REACTIVE]) {
        return target;
      }
    // 这个是 把之前已经创建好的 Proxy 放在这里,如果再创建的话 就先去找,找到了就返回之前的响应
      if(reactMap.get(target)) {
        return reactMap.get(target);
      }
    
      // 通过
      const proxy = new Proxy(target, {
        get(target, key, receiver) {
            if(key == IS_REACTIVE) {
                return true;
            }
            // return target[key] 跟 Reflect.get(target, key, receiver)的区别
            // receiver 就是相当于代理对象就是这个时候的Proxy, Reflect 中的receiver 相当于把他的this指向 receiver
            return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
            return Reflect.set(target, key, value, receiver);
        }
      });
    
      reactMap.set(target, proxy);
      return proxy;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    index.html

    
    
    
        
        
        
        Document
    
    
        
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    Reflect对象是一个全局的普通的对象。Reflect的原型就是Object.

    Reflect是ES6为了操作对象而新增的API, 为什么要添加Reflect对象呢?它这样设计的目的是为了什么?

    1)将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上,那么以后我们就可以从Reflect对象上可以拿到语言内部的方法。

    2)在使用对象的 Object.defineProperty(obj, name, {})时,如果出现异常的话,会抛出一个错误,需要使用try catch去捕获,但是使用 Reflect.defineProperty(obj, name, desc) 则会返回false

    // 可以参考一下这篇文章 就知道了,为什么要这个样子写
    return target[key] 跟 Reflect.get(target, key, receiver)的区别
    Reflect的用法

  • 相关阅读:
    【ASP.NET Core】MVC模型绑定——实现同一个API方法兼容JSON和Form-data输入
    网页端扫码通过公众号实现微信授权登录
    跨平台应用开发进阶(三十):uni-app 实现视频直播
    电子统计台账:处理时间与名称所在行有交错的流水账格式
    【动态规划】392. 判断子序列、115. 不同的子序列
    Dockerfile RUN
    Semantic Kernel 学习笔记1
    龙迅LT89101L 是一款高性能 MIPI 至 LVDS 电平转换器
    Android 播放mp3文件
    财务数字化转型是什么?_光点科技
  • 原文地址:https://blog.csdn.net/hl971115/article/details/126896779