Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 概览

  • 响应式系统

    • Proxy对象代理
    • effect函数
    • ref和reactive
      • computed函数
      • 响应系统里的工具函数
    • runtime运行时

    • runtime-core

    • compiler编译

    • 《Vue3源码》笔记
    • 响应式系统
    东流
    2024-05-29
    目录

    ref和reactive

    # 概述

    ref和reactive是工作中最常用到的定义响应式数据的方法, 二者的核心是基于Proxy处理的。代码参考于 vue3 源码@vue/reactivity

    # ref

    ref是基于RefImpl类实现的,如下所示,每一个ref包装过返回的对象都会有两个属性:__v_isShallow和__v_isRef。由shallowRef包装的对象__v_isShallow的值为true,ref定义的为false;_v_isRef是ref对象的标志位,表示这是一个ref对象。

    在RefImpl类的构造器中,如果是ref包装的,则还会调用toReactive方法, 这个方法借助于 vue3 的另一个模块@vue/shared的方法,用以区分是否为对象,亦如下面所示,如果value是对象,则会调用reactive方法,由此可以看出ref(p)中,如果p是对象,其本质上还是会调用reactive方法。

    RefImpl类中定义了get和set,当我们获取或者设置ref对象的.value时会分别调用对应的方法

    • get value:这个里面调用了 trackRefValue方法,主要作用就是依赖收集
    • set value: 方法中调用了shared 工具库中的方法,通过Object.is比较新值和原始值是否相等,如果不等,则重新赋值原始值,并调用triggerRefValue方法,进行消息派发
    const toReactive = (value) =>
      shared.isObject(value) ? reactive(value) : value; // 利用typeof判断value是否为对象
    
    class RefImpl {
      constructor(value, __v_isShallow) {
        this.__v_isShallow = __v_isShallow;
        this.dep = void 0;
        this.__v_isRef = true;
        this._rawValue = __v_isShallow ? value : toRaw(value); //原始值
        this._value = __v_isShallow ? value : toReactive(value); //值
      }
      get value() {
        trackRefValue(this);
        return this._value;
      }
      set value(newVal) {
        const useDirectValue =
          this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
        newVal = useDirectValue ? newVal : toRaw(newVal);
        if (shared.hasChanged(newVal, this._rawValue)) {
          this._rawValue = newVal;
          this._value = useDirectValue ? newVal : toReactive(newVal);
          triggerRefValue(this, 4);
        }
      }
    }
    
    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

    # reactive

    reactive 可以递归地将其属性也响应式。 如下所示,reactive首先判断参数target是否只读,如果只读,返回target;否则调用createReactiveObject方法,顾名思义,该方法就是创建一个响应式的对象

    function reactive(target) {
      if (isReadonly(target)) {
        return target;
      }
      return createReactiveObject(
        target,
        false,
        mutableHandlers,
        mutableCollectionHandlers,
        reactiveMap
      );
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # createReactiveObject 方法

    其内部逻辑如下,

    function createReactiveObject(
      target,
      isReadonly2,
      baseHandlers,
      collectionHandlers,
      proxyMap
    ) {
      if (!shared.isObject(target)) {
        return target;
      }
      if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) {
        return target;
      }
      const existingProxy = proxyMap.get(target);
      if (existingProxy) {
        return existingProxy;
      }
      const targetType = getTargetType(target);
      if (targetType === 0 /* INVALID */) {
        return target;
      }
      const proxy = new Proxy(
        target,
        targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers
      );
      proxyMap.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

    # shallowReactive

    编辑 (opens new window)
    上次更新: 2024/07/02, 09:57:01
    effect函数
    computed函数

    ← effect函数 computed函数→

    最近更新
    01
    GeoJSON
    05-08
    02
    Circle
    04-15
    03
    CircleMarker
    04-15
    更多文章>
    Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式