当前位置: 首页 > news >正文

【Vue3源码】第六章 computed的实现

【Vue3源码】第六章 computed的实现

上一章节我们实现了 ref 及其它配套的isRef、unRef 和 proxyRefs API。这一章开始实现computed计算属性。

认识computed

接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 getset 函数的对象来创建一个可写的 ref 对象。

computed计算属性最重要的功能就是:仅会在其响应式依赖更新时才重新计算。

为什么需要缓存呢?想象一下我们有一个非常耗性能的计算属性 list,需要循环一个巨大的数组并做许多计算逻辑,并且可能也有其他计算属性依赖于 list。没有缓存的话,我们会重复执行非常多次 list 的 getter,然而这实际上没有必要!如果你确定不需要缓存,那么也可以使用方法调用。

单元测试代码

首先看单元测试代码:

我们需要实现懒计算(响应式依赖更新时才重新计算)

所以我们测试内容主要需要实现的步骤有以下三步:

  • 当getter作为参数传入computed时,不会触发计算
  • 当访问计算属性的返回值cValue会被触发一次,响应式依赖如果不进行更新,重复访问时不会再次触发计算
  • 响应式依赖更新时才重新计算
import { computed } from "../computed";
import { reactive } from "../reactive";describe("computed", () => {it("happy path", () => {const value = reactive({foo: 1,});const getter = computed(() => {return value.foo;});value.foo = 2;expect(getter.value).toBe(2);});it("should compute lazily", () => {const value = reactive({foo: 1,});const getter = jest.fn(() => {return value.foo;});const cValue = computed(getter);// lazyexpect(getter).not.toHaveBeenCalled();expect(cValue.value).toBe(1);expect(getter).toHaveBeenCalledTimes(1);// should not compute againcValue.value;expect(getter).toHaveBeenCalledTimes(1);// should not compute until neededvalue.foo = 2;expect(getter).toHaveBeenCalledTimes(1);// now it should computeexpect(cValue.value).toBe(2);expect(getter).toHaveBeenCalledTimes(2);// should not compute againcValue.value;expect(getter).toHaveBeenCalledTimes(2);});
});

实现代码

计算属性是基于现有响应式对象而衍生出来的,它的实现代码中就有创建ReactiveEffect对象的流程。

computedRefImpl类是computed API的核心。

从ReactiveEffect的构造方法和计算属性创建ReactiveEffect对象源码可知,构造函数的fn回调方法就是getter方法,而schedule方法就是设置计算属性为脏数据的匿名方法。

import { ReactiveEffect } from "./effect";class computedRefImpl {private _getter: any; //保存getterprivate _dirty: boolean = true; //将数据标记为藏数据控制计算属性更新private _value: any; // 保存run方法返回的value值private _effect: any; //保存ReactiveEffect实例constructor(getter) {this._getter = getter;//通过ReactiveEffect类中的scheduler选项实现每次new ReactiveEffect才能更新计算值this._effect = new ReactiveEffect(getter, () => {// 通过_dirty实现依赖触发更新内容if (!this._dirty) {// 标记脏数据this._dirty = true;}});}get value() {// get => get value// 当依赖的响应式的对象的值发生改变的时候才会更新// effectif (this._dirty) {this._dirty = false;// 获取到 fn 的返回值this._value = this._effect.run();}return this._value;}
}export function computed(getter) {return new computedRefImpl(getter);
}
  • constructor

    构造函数新建了一个ReactiveEffect实例,所有的响应式都是通过这个对象来实现的,实例中我们通过ReactiveEffect类中scheduler的设计,停止了run方法的执行转而执行我们scheduler中传入的匿名函数。

    • 第一个参数是getter方法,这个方法会进行依赖收集和数据计算。
    • 第二个方法则是scheduler依赖变更时的回调方法,这个方法将数据标识为脏数据,表示下次读取时需要重新计算,并且触发依赖更新。

    是的之前的文章《【Vue3源码】第二章 effect功能的完善上》有埋下scheduler实现的伏笔,它在computed中收回~

  • get value()

    这是计算属性的重点,核心逻辑是判断当前缓存数据是否脏数据,是脏数据就重新计算。其中ReactiveEffect对象的run方法会调用getter方法进行计算。

computed流程图

在这里插入图片描述
到了这里,reactivity文件夹的学习就告一段落了下一part开始学习runtime-core文件夹
下节预告:初始化 component 主流程

相关文章:

【Vue3源码】第六章 computed的实现

【Vue3源码】第六章 computed的实现 上一章节我们实现了 ref 及其它配套的isRef、unRef 和 proxyRefs API。这一章开始实现computed计算属性。 认识computed 接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。…...

Java基础之注解

3.注解 3.1概述【理解】 概述 对我们的程序进行标注和解释 注解和注释的区别 注释: 给程序员看的注解: 给编译器看的 使用注解进行配置配置的优势 代码更加简洁,方便 3.2自定义注解【理解】 格式 public interface 注解名称 { ​ public 属性类型 属性名() default 默认值…...

三、线性表

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 自学JAVA数据结构笔记,跟学视频为:黑马程序员Java数据结构与java算法全套教程…...

C++统计方形

统计方形 内存限制:256 MB 时间限制:1 S 题目描述 有一个n*m方格的棋盘,求其方格包含多少正方形、长方形(此处长方形不包含正方形) 输入格式 输入存在多组测试数据。每组测试数据输入两个整数n,m,数字不超…...

Tina_Linux配网开发指南

OpenRemoved_Tina_Linux_配网_开发指南 1 概述 1.1 编写目的 介绍Allwinner 平台上基于wifimanager-v2.0 的WiFi 配网方式,包括softap(WiFi ap 模式热点配网),soundwave(声波配网),BLE(蓝牙低功耗配网)。 1.2 适用范围 • allwinner 软件平台tina v5.0 版本及以…...

高频面试题|RabbitMQ如何防止消息的重复消费?

一. 前言最近有很多小伙伴开始找工作,在面试时,面试官经常会问我们这样一个题目:RabbitMQ如何防止重复消费?有很多小伙伴这个时候都在想,消息怎么还会重复消费呢???.......所以他们在面试后就跑来问壹哥,针对这个比…...

黑盒测试用例设计方法-边界值分析法

目录 一、边界值定义 二、边界值的考虑 三、边界值的优化 四、边界值的设计用例的步骤 五、案例 六、边界值的类型 一、边界值定义 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充,这种情况下…...

项目风险管理中不可忽视的5个关键点

1、风险意识非常重要 项目经理必须要有风险意识,并不是项目计划做好就万事大吉,而是需要对项目风险进行预判,时刻保持风险意识,及时发现和处理项目风险。 项目风险管理关键:风险意识​ 2、建立组织风险资产库 寻…...

Linux->进程地址空间

目录 前言: 1. 程序地址空间回顾 2. 进程空间是什么 3. 进程地址空间与内存 4. 进程地址空间和内存的关联 5. 为什么要有进程地址空间 前言: 我们在平时学习的过程当中总是听到栈、堆、代码段等等储存空间,但是这些东西到底是什么&…...

【奶奶看了也不会】AI绘画 Mac安装stable-diffusion-webui绘制AI妹子保姆级教程

1.作品图 2.准备工作 目前网上能搜到的stable-diffusion-webui的安装教程都是Window和Mac M1芯片的,而对于因特尔芯片的文章少之又少,这就导致我们还在用老Intel 芯片的Mac本,看着别人生成美女图片只能眼馋。所以小卷这周末折腾了一天&#…...

基于stm32电梯管理系统设计

基于stm32电梯管理系统设计这里记录一下以前自己做的嵌入式课程设计,报告中的图片和文字太多了,全部一个一个把搬过来太麻烦了,需要完整文本和代码自行q我963160156,也可在微信公众号 *高级嵌入式软件* 里回复 *电梯* 查看完整版文章摘要关键…...

Spring中的FactoryBean 和 BeanFactory、BeanPostProcessor 和BeanFactoryPostProcessor解析

文章目录FactoryBean 和 BeanFactory后置处理器BeanPostProcessor 和 BeanFactoryPostProcessorBeanPostProcessorBeanFactoryPostProcessorFactoryBean 和 BeanFactory BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的…...

【C++从入门到放弃】类和对象(上)

🧑‍💻作者: 情话0.0 📝专栏:《C从入门到放弃》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢! 类和对…...

什么牌子的蓝牙耳机便宜好用?四款高品质蓝牙耳机推荐

随着时代的发展,蓝牙耳机的使用频率越来越高,不少人外出时除了带手机外,蓝牙耳机也成为了外出必备的数码产品之一。现在的蓝牙耳机品牌众多,什么牌子的蓝牙耳机便宜好用?下面,我来给大家推荐四款高品质的蓝…...

eddsa 算法

信息安全课程设计:eddsa 算法 一、项目要求 使用 C 语言开发;可以实现公私钥生成、签名、认证;只需要手动输入明文,代码会自动生成公私钥、签名、认证;记录公私钥生成、签名、认证的时间;在 VS 上运行&am…...

Xcode Developer Document 开发者文档

总目录 iOS开发笔记目录 从一无所知到入门 文章目录IntroDeveloper Documentation 打开方式菜单栏点击 | 快捷键方式另一种打开方式Intro 2016年我在学校学Java的时候,要查某个Java类/方法的用法还得自己手动下载一种.chm格式的开发文档文件&#xff0c…...

IntelliJ插件开发教程之新建项目

JetBrains公司系列产品IDEA、WebStrom、PyCharm、CLion、GoLand等都是基于IntelliJ Platform开发而成,掌握IntelliJ插件开发技能便能拥有提升开发效率的终极武器。本教程Demo源码请微信公众号“开发效率”进行获取。阅读原文如果您是JetBrains产品的用户&#xff0c…...

解决SpringBoot中@RequestBody不能和Multipart同时传递的问题

问题描述 今天在做文件上传的时候,遇到了这么一个错误日志: Resolved[org.springframework.web.HttpMediaTypeNotSupportedException: Content type ‘multipart/form-data;boundary--------------------------771899451541318130280588;charsetUTF-8’…...

【华为OD机试模拟题】用 C++ 实现 - 统计匹配的二元组个数(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明统计匹配的二元组个数题目输入输出描述示例一输入输出说明示例二输入输出说明备注Code使用说明 参加华为od机试,一定要注意不要完全背诵代码&...

Vuex 面试题总结 的历史汇总!

一.vuex是什么?怎么使用?哪种功能场景使用它? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。简单来说就是:应用…...

Redis缓存更新策略与缓存穿透、雪崩等问题的解决

文章目录一、缓存更新策略1、三种策略2、策略选择3、主动更新的方案二、缓存存在的问题1、缓存穿透2、缓存雪崩3、缓存击穿三、解决缓存问题1、自定义分布式锁2、解决缓存穿透问题3、解决缓存击穿问题一、缓存更新策略 1、三种策略 内存淘汰:redis自带的内存淘汰机…...

OSI和TCP/IP网络模型细讲

文章目录一、OSI七层参考模型二、TCP/IP体系结构三、TCP/IP参考模型四、沙漏计时器形状的TCP/IP协议族五、两种国际标准对比相似之处不同之处一、OSI七层参考模型 OSI参考模型共分为7层,低三层面向通信,可用软硬件实现;高三层面向信息处理&am…...

【正点原子FPGA连载】第十九章FreeRtos Hello World实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第十九章FreeRto…...

php mysql高校田径运动会成绩管理系统

第一章 引言 1 1.1 选题背景 1 1.2 编写目的 2 1.3 目标 2 1.4 功能需求 3 第二章 开发工具介绍 4 2.1 PHP 4 2.2 APACHE 5 2.3 MYSQL数据库 5 2.4 运行环境 WINDOWS XP 6 2.5 XAMPP 6 2.6 DREAMWEAVE8 6 2.7 EDITPLUS 7 第三章 需求…...

scrum敏捷项目管理软件三款

Leangoo领歌Leangoo是国产的一个项目管理软件,www.leangoo.com , 专门的Scrum敏捷开发工具,看板的管理方式,高度可视化。它支持敏捷开发全流程。从产品路线图-需求-迭代-缺陷-测试-上线。燃尽图,工作量,迭代…...

【项目设计】高并发内存池(二)[高并发内存池整体框架设计|threadcache]

🎇C学习历程:入门 博客主页:一起去看日落吗持续分享博主的C学习历程博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 也许你现在做的事情,暂时看不到成果,但不要忘记&…...

西电编译原理期末核心考点汇总(期末真题+相关知识点)

文章目录前言一、正规式1.1 相关知识点1.1.1 正规式定义1.1.2 辅助定义1.2 历年真题二、二义文法2.1 相关知识点2.1.1 二义性概念2.2 历年考题三、全部短语、直接短语和句柄3.1 相关知识点3.1.1 短语,直接短语和句柄定义3.1.2 短语,直接短语和句柄例题3.…...

追梦之旅【数据结构篇】——详解C语言实现二叉树

详解C语言实现二叉树~😎前言🙌什么是二叉树?二叉树的性质总结:整体实现内容分析💞1.头文件的编写:🙌2.功能文件的编写:🙌1)前序遍历的数值来创建树——递归函…...

独家 | Gen-1——可以改变视频风格的AI模型

翻译:吴振东校对:张睿毅本文约1000字,建议阅读3分钟 本文简单介绍了Runway公司的发展史,以及他们新推出的生成式AI模型Gen-1,可用于通过应用文本提示或者参考图像所指定的任意风格,将现有视频转换为新视频。…...

戴尔dell inspiron-5598电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网,转载需注明出处。硬件型号驱动情况主板X99 K9 v2 Machinist处理器i5-10210U / *i7-10510U已驱动内存20GB已驱动硬盘1000GB SAMSUNG 860 QVO SATA已驱动显卡Intel UHD 620已驱动声卡Realtek ALC3204/236已驱动网卡RTL8168H Gigabit Ethernet已…...

wordpress手机端源码/乌海网站seo

最近在工作中要实现一种“流程审批”的功能,查阅资料得知,workFlow技术可以满足我的需求,于是就开始沉下心来好好学习一下这门技术。总结的学习资料也拿出来和大家共享一下。 什么是工作流: 工作流,指的是一系列相互衔接、自动进行…...

苏州北京网站建设/页面关键词优化

安装Linux(如果之前已经有Linux,不用安装,直接安装Hadoop) 参考链接:厦门大学Hadoop安装教程_单机/伪分布式配置 1尝试新建一个名为hadoop的用户并且设置密码(同时添加管理员权限):…...

网站策划运营方案/百度电话号码

据Foss Patents报道,地方法院法官Paul Grewal已命令Google和Oracle的首席执行官Larry Ellison和Larry Page 参加法庭和解会谈 。 由于该案的审判长阿尔苏普(Alsup)法官建议对首席执行官下达命令,因此他们将无法要求审判长否决裁判…...

bootstrap 设置 wordpress 背景/手机百度app免费下载

中国到底多少个程序员?每年计算机专业毕业的有多少?而这些人中真正从事it行业的比例是多少呢?中国的程序员中的地域分布状况又如何呢?以及程序员使用的编程语言比重等等,这一个个问题似乎都深刻的说明了我们程序猿是一…...

网站制作百度/营销型网站的公司

跟着官网的教程学lvgl,在画圆弧的时候发现不知道怎么设置圆弧的粗细。 官网教程没用到,查百度半天也没找着。最后翻函数手册发现原来 lv_style_set_arc_width() 这个函数就是用来设置圆弧的粗细的。(我以为是用来设置宽度的) LV…...

网站流量10g/app开发平台开发

一、拼多多做直播的目的?1、拼多多直播毋庸置疑是为了服务商家,帮助商家快速变现;2、丰富商家的营销玩法,目前5g时代,直播势在必行;3、为了加大促进私域流量的一个转换;4、无论是中小型还是头部…...