VUE设计与实现共读系列之ref的实现【响应式原理】

前言

我们先顺一下vue使用响应式数据的流程:
vue 是通过 refreactive 来创建响应式值,改变响应式值,视图跟着发生变化。
我们今天就来看一下refreactive是如何实现的

准备

首先,打开ref函数的位置
在这里插入图片描述
我们可以看到一个被ref包裹的响应式数据,其实是一个RefImpl对象
在这里插入图片描述

1. 创建ref

export function ref(value) {return createRef(value);
}function createRef(value) {const refImpl = new RefImpl(value);return refImpl;
}

可以看到创建一个ref对象的本质就是创建一个RefImpl装饰对象

2. 编写RefImpl对象

export class RefImpl {private _rawValue: any; // 原值private _value: any;	// 代理值public dep;	// 依赖数组:用来存放依赖public __v_isRef = true; // 区分是否是ref这个对象类型constructor(value) {this._rawValue = value;// 看看value 是不是一个对象,如果是一个对象的话// 那么需要用 reactive 包裹一下this._value = convert(value);this.dep = createDep();  // 创建effect对象}get value() {// 收集依赖trackRefValue(this);return this._value;}set value(newValue) {// 当新的值不等于老的值的话,// 那么才需要触发依赖if (hasChanged(newValue, this._rawValue)) {// 更新值this._value = convert(newValue);this._rawValue = newValue;// 触发依赖triggerRefValue(this);}}
}

❤️❤️ 为什么要有_rawValue_value呢?

答:_value用来保存我们加工后的具有响应式的对象,_rawValue保存的是原始的值

3. 依赖收集和触发

依赖收集

// trackRefValue
export function trackRefValue(ref) {if (isTracking()) { // 判定师傅可以进行收集trackEffects(ref.dep);}
}// trackEffects
let activeEffect = void 0;export function trackEffects(dep) {// 用 dep 来存放所有的 effectif (!dep.has(activeEffect)) {dep.add(activeEffect);(activeEffect as any).deps.push(dep);}
}
  • activeEffect:作用是用一个全局变量存储被注册的副作用函数

依赖触发

在这里插入图片描述

// ref.ts
export function triggerRefValue(ref) {triggerEffects(ref.dep);
}// effect.ts
export function triggerEffects(dep) {// 执行收集到的所有的 effect 的 run 方法for (const effect of dep) {if (effect.scheduler) {// scheduler 可以让用户自己选择调用的时机// 这样就可以灵活的控制调用了// 在 runtime-core 中,就是使用了 scheduler 实现了在 next ticker 中调用的逻辑effect.scheduler();} else {effect.run();}}
}

思考

  1. ref创建的值 .value有什么用?

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

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

相关文章

SmartSoftHelp8,SQL语句优化,耗时,返回数据行,kb

SQL语句优化 SQL语句耗时测试,耗时优化 SQL语句查询返回数据行统计 SQL语句查询返回数据大小统计,kb 总量统计 下载地址:https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

施人玫瑰手留余香和影像组学、医学人工智能未来漫谈

今天收到进阶班学员的留言: 提示:本文有硬核软文嫌疑,请慎重阅读。“ 我用您给我们讲的CLEAR,与一个审稿人进行了battle。有理有据。评估下来,我感觉我们的文章还是挺符合CLEAR的。” 我从来不排斥在商言商&#xff0…

12月02日每日信息差

_灵感 🎖 六国入境免签首日2029人次享便利 🎄 国内首个超大规模“光伏气膜”项目在江苏投运 🌍 东京将推出氢气交易市场 🌋 中国疾控中心:建议尽早接种流感疫苗,尤其是老年人和儿童 🎁 偏高1.…

MySQL列操作记录

在 MySQL 中,你可以使用多种命令和语句来执行列操作,包括添加、修改、删除列等。以下是一些与列操作相关的常用 MySQL 命令和语句: 1. 添加列: 添加新列到表格中: ALTER TABLE table_name ADD COLUMN column_name d…

01_学习使用javax_ws_rs_上传文件

文章目录 1 前言2 Maven 依赖3 上传接口4 如何解析 MultipartFormDataInput5 结语 1 前言 使用 Spring MVC 来处理文件上传,想必是大家耳熟能详的了,如下代码: ResponseBody PostMapping("/upload") public String upload(Request…

【Qt开发流程】之事件系统1:事件系统描述及键盘事件

Qt的事件系统 在Qt中,事件是对象,派生自抽象的QEvent类,它表示应用程序内部发生的事情或作为应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理,但它们与小部件特别相关。以下描述了在典型应用程序中…

MATLAB算法实战应用案例精讲-【图像处理】数字图像处理(补充篇)

目录 算法原理 数字图像处理常用算法 1.二值化: 2.海报化 3.灰度化

基于ZLMediaKit的webrtc实时视频传输demo搭建

环境 ubuntu 20.04 ​ gcc version 9.4.0 ​ cmake version 3.16.3 部署ZLMediaKit流媒体服务器 安装openssl 首先可以检查一下自己的openssl的版本如果是1.1.1以上就可以忽略这一步 wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz tar -xvzf openssl-1.1.1k…

【新论文】【模型攻击】DiffAttack 针对基于扩散的对抗性净化的逃避攻击

DiffAttack: Evasion Attacks Against Diffusion-Based Adversarial Purification 作者: Mintong Kang; Dawn Song; Bo Li 链接: http://arxiv.org/pdf/2311.16124v1 备注: Accepted to NeurIPS 2023 摘要: 基于扩散的净化防御利用扩散模型去除对抗样本的精心设计的扰动&#…

酷开科技 | 酷开系统,让家庭娱乐方式焕然一新!

在这个快节奏的社会,家庭娱乐已成为我们日常生活中不可或缺的一部分,为了给家庭带来更多欢笑与感动,酷开科技发力研发出拥有丰富内容和技术的智能电视操作系统——酷开系统,它集合了电影、电视剧、综艺、游戏、音乐等海量内容&…

我的2023年12月02日对文章发送的一个测试

1 Markdown.com.cn 简介 支持自定义样式的 Markdown 编辑器支持微信公众号、知乎和稀土掘金点击右上方对应图标,一键复制到各平台 2 Markdown语法教程 2.1 标题 不同数量的#可以完成不同的标题,如下: 一级标题 二级标题 三级标题 2.2…

C语言-指针_01

指针基础 1. 概述 地址编号:计算机为了存储数据,每一个程序在 32位 机中 占4G,最小操作单位 是 一个字节,每一个字节都有其对应的地址,该地址就是 地址编号。 指针:地址编号这个数据 的 数据类型。 指针变…

Java数组与List互换

asList():将数组转成list //将数组转换为listint[][] nums {{7,0},{4,4},{7,1},{5,0},{6,1},{5,2}};List<int[]> list new LinkedList<>(Arrays.asList(nums));for (int[] ints :list) {System.out.println(ints[0] " " ints[1]); //遍历list}toAr…

TPC通信-BS架构

BS架构-基本原理 BS框架基本原理 使用线程池对BS架构进行优化

docker部署typecho博客

文章目录 1.安装git2.安装compose3.拉取仓库4.创建目录5.配置文件修改6.启动容器7.修改MYSQL数据库8.安装成功9.参考GitHub文档 1.安装git 安装git yum -y install git2.安装compose &#xff08;docker安装参考&#xff1a;docker基本知识&#xff09; 确保已经安装了 Doc…

爬虫学习-基础(HTTP原理)

目录 一、URL和URI 二、HTTP和HTTPS &#xff08;1&#xff09;HTTP &#xff08;2&#xff09;HTTPS &#xff08;3&#xff09;HTTP与HTTPS区别 &#xff08;4&#xff09;HTTPS对HTTP的改进&#xff1a;双问的身份认证 三、TCP协议 &#xff08;1&#xff09;TCP三次握手…

⭐ Unity 里让 Shader 动画在 Scene 面板被持续刷新

写 Unity Shader的时候&#xff0c;只有播放状态下的 Game 面板能看到Shader 顺畅的动态效果&#xff0c;不方便。 想要带有动态效果的 Shader 在 Scene 面板持续更新动画&#xff0c;只需要打开一个开关就能让 Scene 持续刷新动画了。 感谢大家的观看&#xff0c;您的点赞和关…

android 13.0 launcher3中workspace app列表页不显示某个app图标

1.概述 在13.0的系统ROM定制化开发中,Launcher3 workspace的app列表页 会负责加载系统中app的所有图标 但针对某个不需要显示在桌面的app图标需要过滤掉 所以需要在加载和更新的时候过滤 需要更改两处地方, 一处是 加在列表时 一处是安装卸载app 更新app列表时,接下来具体分…

learn2learn环境配置(2023年12月)

learn2learn是元学习方向的一个非常实用的库&#xff0c;但其发布时间较早&#xff0c;与最新版本的pytorch可能存在一些兼容性问题&#xff0c;在2023年12月这个时间进行安装时会遇到一些问题&#xff0c;以下是我遇到的问题及解决的方法。 1. 在我第一次直接配置“pip instal…

Cpp之旅(学习笔记)第9章 标准库

C之旅&#xff08;学习笔记&#xff09;第9章 标准库 当无知稍纵即逝时&#xff0c;又何必浪费时间学习呢&#xff1f; ——霍布斯 9.1 引言 第9~18章将对重要的标准库工具和方法给出一个概要性的介绍。如&#xff1a;string、ostream、variant、vector、map、path、unique_p…