vue3源码(五)ref、toRef、toRefs、proxyRefs

news2025/1/9 6:00:14

1.ref

功能

  • refreactive功能类似,都是将数据变为响应式,ref通常用来定义基本类型数据,如字符串、数字、布尔值等。而reactive用来定义对象(或数组)类型数据。虽然ref也可以用来定义对象或数组类型的数据,但内部会通过reactive转为代理对象。
  • refscript标签中必须.value才能使用 在template标签中则不用

使用

	  let flag = ref(false);
      effect(() => {
        app.innerHTML = flag.value ? "111" : "222";
      });
      setTimeout(() => {
        flag.value = true;
      }, 1000);

实现

使用类实现,在get方法中收集effect,在set时触发收集到的effect

import { activeEffect, trackEffect, triggerEffects } from "./effect";
import { toReactive } from "./reactive";
import { createDep } from "./reactiveEffect";

export function ref(value) {
  return createRef(value);
}

function createRef(value) {
  return new RefImpl(value);
}

class RefImpl {
  public __v_isRef = true; //ref 标识
  public _value; // 用来保存ref的值
  public dep = undefined; // 用于收集对应的effect
  constructor(public rawValue) {
    this._value = toReactive(rawValue);
  }
  get value() {
    trackRefValue(this);
    return this._value;
  }
  set value(newValue) {
    if (newValue != this.rawValue) {
      this.rawValue = newValue;
      this._value = newValue;
      triggrtRefValue(this);
    }
  }
}

function trackRefValue(ref) {
  if (activeEffect) {
    trackEffect(
      activeEffect,
      (ref.dep = createDep(() => (ref.dep = undefined), "undefined"))
    );
  }
}
function triggrtRefValue(ref) {
  let dep = ref.dep;
  if (dep) {
    triggerEffects(dep);
  }
}

2.toRef

功能

  • toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。
  • 返回的是一个指向源对象属性的 ref 引用,任何对该引用的修改都会同步到源对象属性上。
  • 使用 toRef 时需要传入源对象和属性名作为参数。

首先定义一个reactive对象,将对象进行结构赋值重组后,得到的对应不再具有响应式特性

 let state = reactive({ name: "cwj", age: 18 });
      console.log(state, {...state});

在这里插入图片描述
使用toRef转换对象中的某个属性,返回一个ObjectRefImpl

let name = toRef(state, "name");  // 基于proxy取值
      let age = toRef(state, "age"); 
      console.log(name,name.value);
      console.log(age.value);

在这里插入图片描述

实现

class ObjectRefImpl {
  public __v_isRef = true;
  constructor(public _object, public _key) {}
  get value() {
    return this._object[this._key];
  }
  set value(newValue) {
    this._object[this._key] = newValue;
  }
}

export function toRef(object, key) {
  return new ObjectRefImpl(object, key);
}

toRefs

功能

  • toRefs 函数可以将一个响应式对象转换为一个普通的对象,该对象的每个属性都是独立的 ref 对象。
  • 返回的对象可以进行解构,每个属性都可以像普通的 ref 对象一样访问和修改,而且会保持响应式的关联。
  • toRefs 的使用场景主要是在将响应式对象作为属性传递给子组件时,确保子组件可以正确地访问和更新这些属性。

使用

 let state = reactive({ name: "cwj", age: 18 });
      let { name, age } = toRefs(state);
      console.log(name, age);

在这里插入图片描述

实现

export function toRefs(object) {
  const res = {};
  for (let key in object) {
    res[key] = toRef(object, key);
  }
  return res;
}

proxyRefs

功能

前面我们提到ref数据在template中使用时不需要像在script标签中.value才能使用

使用:主要用于template中,此处为验证功能

let state = reactive({ name: "cwj", age: 18 });
      let proxy = proxyRefs({ ...toRefs(state),a:20 });
      proxy.age = 100
      proxy.a = 11
      effect(() => {
        console.log(proxy.name, proxy.age, proxy.a);
      });

实现


export function proxyRefs(objectWithRef) {
  return new Proxy(objectWithRef, {
    get(target, key, receiver) {
      let r = Reflect.get(target, key, receiver);
      return r.__v_isRef ? r.value : r;
    },
    set(target, key, value, receiver) {
      const oldValue = target[key];
      if (oldValue.__v_isRef) {  // 如果老值还是一个ref
        oldValue.value = value;
        return true
      } else {
        return Reflect.set(target, key, value, receiver);
      }
    },
  });
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1854986.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rxjava2最全面的解析

说到区别,可能有的小伙伴会问,我没看过rxjava1。可以直接看rxjava2么。个人觉得不必要,因为 rxjava2.x 是按照 Reactive-Streams specification 规范完全的重写的,完全独立于 rxjava1.x 而存在,它改变了以往 rxjava1的…

Springboot 项目启动时扫描所有枚举并存入缓存(redis)

为什么这么做? 为了springboot 注解属性转换字典方便一点(使用缓存的方式在Springboot 启动时获取字典数据) 在启动时会扫描com.vehicle.manager.core.enumerate包下的所有枚举(包括类中的内部枚举),并取出对应属性以json的方式存入redis 目录结构如下: RedisUtil可以在Red…

已解决javax.management.BadStringOperationException异常的正确解决方法,亲测有效!!!

已解决javax.management.BadStringOperationException异常的正确解决方法,亲测有效!!! 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 分析错误日志 检查字符串值合法性 确认字符串格式 优化代码逻辑 增加…

【数据结构与算法】图论 详解

何为完全图、稀疏图、稠密图。 完全图:完全图是一种简单的无向图,其中每对不同的顶点之间都恰好有一条边。对于有n个顶点的完全图,它包含n(n-1)/2条边。在有向图中,如果任意两个顶点之间都存在方向相反的两条边,包含n(…

汇编快速入门

一.基础知识 1.数据类型 DB(Define Byte,字节类型 占位8位bit 1字节) 范围:DB可以用来定义(无符号、有符号)整数(包含二、十、十六进制)和字符 语法:a DB 数据个数…

C++基础知识——引用

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:Yan. yan.                        …

热电阻温度计的测量电路

热电阻温度计的测量电路,为达到高精度测量,通常会采用电桥测量原理,并结合适当的热电阻类型和连接方式。 惠斯通电桥是用于测量一组电阻式元件阻值变化的电路。该电路具有两个并联电阻支路,充当激励电压 VEXCITATION 的分压器。每…

C++ 教程 - 04 类的使用

文章目录 类的定义类定义案例构造函数 类的定义 C 在 C 语言的基础上增加面向对象编程,类是用于指定对象的形式,是一种用户自定义的数据类型,封装了数据和函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象…

LLM技术全景图:技术人必备的技术指南,一张图带你掌握从基础设施到AI应用的全面梳理

LLM技术全景图:技术人必备的技术指南,一张图带你掌握从基础设施到AI应用的全面梳理 LLM 技术图谱(LLM Tech Map)是将 LLM 相关技术进行系统化和图形化的呈现,此图谱主要特点是“专注于技术人视角”,不求从…

【吊打面试官系列-Mysql面试题】视图有哪些优点?

大家好,我是锋哥。今天分享关于 【视图有哪些优点?】面试题,希望对大家有帮助; 视图有哪些优点? 答: (1) 视图能够简化用户的操作; (2) 视图使用户能以多种角度看待同一数据; (3) 视…

深入学习Java1213新特性

一、关于Java生态圈 二、Java老矣,尚能饭否? 三、JDK各版本主要特性 四、JDK与IDE的下载与安装 五、Java12新特性 1.switch表达式(预览) 2.Shenandoah GC:低停顿时间的GC(预览) 3.JVM常量API 4.微基准测试套…

Vue76-路由对浏览器历史记录的影响

一、push模式 默认是push 二、replace模式 替换当前记录! (当前指针指向的那一条记录) 三、小结

Tobii Pro Lab 1.232是全球领先的眼动追踪研究实验软件

Tobii Pro Lab是全球领先的眼动追踪研究实验软件。软件功能强大且拥有友好的用户界面,使眼动追踪研究变得更加简单、高效。该软件提供了很高的灵活性,可运行高级实验,深入了解注意力和认知过程。 获取软件安装包以及永久授权联系邮箱:289535…

QT事件处理系统之二:窗口部件的事件拦截,以及事件的传递顺序

1、案例说明 在父窗口中为selfLineEdit窗口安装事件过滤器,这样我们可以在父窗口中首先拦截来自于selfLineEdit本身产生的事件,并且决定该事件最终是否继续传递到selfLineEdit窗口本身。 2、关键代码 selfLineEdit.cpp #include "selfLineEdit.h" #include &l…

getPhysicalNumberOfCells获取列数不是合并前实际列数

问题就是:有的导入复杂表头被合并的单元格有默认空字符串,有的直接不存在这个单元格 实际我需要下面这种情况 断点可以看到这个导入第一行合并了,被合并单元格还有默认的空字符串 解决办法就是在合并单元格里面判断,不是第一行第一列都设置…

软件培训方案(Word原件)

1. 培训目的 2. 培训方式 3. 培训内容 4. 培训讲师 5. 培训教材 6. 培训质量保证 软件全套资料:本文末个人名片直接获取或者进主页。

利用定时器1产生全双工软件串口

代码; /*《AVR专题精选》随书例程3.通信接口使用技巧项目:使用AVR定时器1和外中断实现全双工软件串口文件:softuart.c说明:软件串口驱动文件作者:邵子扬时间:2012年12月16日*/ #include "softuart.h"// 内部…

数据库的概念-数据库、数据库管理系统、数据库系统、数据库管理员、数据库设计人员、开发管理使用数据库系统的人员

一、数据库(DB) 1、数据库就是存储数据的仓库,只不过这个仓库是在计算机存储设备上 2、严格的说,数据库是长期存储在计算机内、有组织的、统一管理的、可共享的相关数据的集合 3、数据库应是为一个特定目标而设计、构建并装入数…

阅读笔记:明朝那些事儿妖孽横行的宫廷

明朝那些事儿第四部看完了,合上书本给我印象比较深刻的文臣要数王守仁,不愧为明朝的军事家,思想家,文学家,教育家,他经过多年的思索、磨难、追求,终于有一天,在穷乡僻壤,…

PBR网络数据流量分流+NQA联动静态路由

一、实验目的: 企业有两个网段,业务1网段和业务2网段,拓扑图如下, 二、实验要求 pc1报文走左侧链路到达ar1,pc2报文走右侧链路到达ar1,且当ar2或者ar3发生故障时候,可以通过另一个设备到达ar1…