【Vue3源码】第四章 实现isReadonly和isReactive

news2024/11/11 12:57:49

【Vue3源码】第四章 实现isReadonly和isReactive

前言

上一章节我们实现readonly API,并且优化之前写的reactive API。这一章我们实现isReadonlyisReactive两个API。

在这里插入图片描述

1、实现isReactive

在这里插入图片描述

官网是这么介绍的:检查一个对象是否是由 reactive()shallowReactive() 创建的代理。

原理很简单我们来实现一下这个函数~

先看单元测试代码

import { reactive,isReactive } from "../reactive"


describe("reactive",() => {
    it("happy path",() => {
        const originObj = {foo:1}
        const observed = reactive(originObj)
        expect(observed).not.toBe(originObj)
        expect(observed.foo).toBe(1)
        //新增
        expect(isReactive(observed)).toBe(true)
        expect(isReactive(originObj)).toBe(false)
    })
})

实现isReactive

isReactive的原理很简单,我们怎么判断一个对象是否是由reactive()创建的呢?

还记得上一章节中我们在get捕获器中加入的isReadonly的参数吗?

是的这个参数就可以帮我们监测对象是reactive还是readonly,如果是reactive就调用track函数触发依赖
那么isReadonly参数也可以用来判断是否是个reactive()对象

在这里插入图片描述

所以我们可以在reactive.ts文件里新增如下代码:

// 枚举
export const enum ReactiveFlags {
    IS_REACTIVE = "__v_isReactive",
}

// 传入对象后我们会去访问对象
export const isReactive = (value) => {
    return !!value[ReactiveFlags.IS_REACTIVE]
}

首先我们创建了一个枚举

枚举中我们设置一个用户基本不可能设置的key

那么我们就可以通过这个key,去访问对象中key对应的value
如果是个普通对象,访问value[ReactiveFlags.IS_REACTIVE] 自然是返回 undefined 所以直接用 !!undefined 转换成 false返回即可

那么如果是响应式对象呢?

如果是个响应式对象读取对象的值时,那么它就会先触发get捕获器

所以我们要到baseHandlers.ts文件下判断key是否是"__v_isReactive"即可

import { track, trigger } from "./effect"
import { ReactiveFlags } from "./reactive"

function createGetter(isReadonly = false) {
  return function get(target, key) {
    //如果传入的key是ReactiveFlags.IS_REACTIVE
    if (key === ReactiveFlags.IS_REACTIVE) {
      //get捕获器就返回true告诉调用者这是一个reactive对象
      return !isReadonly
    } 

    const res = Reflect.get(target, key)
    if (!isReadonly) {
      track(target, key)
    }
    return res
  }
}

这就是isReactive函数在监测不同对象时的流程图:

在这里插入图片描述

2、实现isReadonly

其实是同理的直接上代码了

reactive.ts

export const enum ReactiveFlags {
    IS_REACTIVE = "__v_isReactive",
    IS_READONLY = "__v_isReadonly"
}

export const isReactive = (value) => {
    return !!value[ReactiveFlags.IS_REACTIVE]
}

export const isReadonly = (value) => {
    return !!value[ReactiveFlags.IS_READONLY]
}

baseHandlers.ts

import { ReactiveFlags } from "./reactive"

function createGetter(isReadonly = false) {
  return function get(target, key) {
    if (key === ReactiveFlags.IS_REACTIVE) {
      //get捕获器就返回true告诉调用者这是一个reactive对象
      return !isReadonly
    } else if (key === ReactiveFlags.IS_READONLY) {
      // 同理返回isReadonly证明是readonly
      return isReadonly
    }

    const res = Reflect.get(target, key)
    if (!isReadonly) {
      track(target, key)
    }
    return res
  }
}

流程图:
在这里插入图片描述
下节预告《vue3源码 优化stop功能》

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

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

相关文章

WebView2 (Chromium) 右键菜单大全

在开发WebView2浏览器时,需要定制右键上下文菜单,但是微软的官方网站上没有详细的菜单,这里整理出来,以方便大家使用。以下是在win11上测试获取的,经过测试win7上稍有不同。一、网页上空白处右键 Target:Pa…

Mybatis Notes

文章目录1 Mybatis 介绍1.1 快速入门2 JDBC2.1 JDBC介绍2.3 JDBC问题分析2.4 Mybatis与JDBC技术对比3 数据库连接池3.1 数据库连接池介绍3.2 数据库连接池产品产品3.3 Druid引入项目4lombok4.1 lombok介绍4.2 lombok使用4.2.1 在pom.xml文件中引入依赖4.2.2 pojo类代码引入1 My…

强化学习 Reinforcement Learning(1) ~ 介绍

1. 强化学习概念和分类 强化学习,Reinforcement Learning 通过价值选行为: Q LearningSarsaDeep Q Network 直接选行为: Policy Gradients 想象环境并从众学习: Model Based RL 1.1 通过环境分类 1.1.1 不理解环境 Model-Fr…

4.5 习题(王晓云 主编)

一、选择题1. 下面( ) 是错误的if 语句&#xff08;设int x,a,b;&#xff09;BA&#xff09;if (ab) x; B&#xff09;if (a<b) x;C&#xff09;if (a-b) x; D&#xff09;if (x ) x;2. 以下程序片段( )。Dvoid main ( ){int x0,y0,z0;if (xyz) printf(“***”);else printf…

RT-Thread SP使用教程

RT-Thread SPI 使用教程 实验环境使用的是正点原子的潘多拉开发板。 SPI从机设备使用的是BMP280温湿度大气压传感器。 使用RT-Thread Studio搭建基础功能。 1. 创建工程 使用RT-Thread Studio IDE创建芯片级的工程。创建完成后&#xff0c;可以直接编译下载进行测试。 2.…

JVM学习篇垃圾收集器ParNewCMS与底层三色标记算法详解

1. 垃圾收集算法 2. 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法&#xff0c;这种算法没有什么新的思想&#xff0c;只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集算法…

因果推断7--深度因果模型综述(个人笔记)

目录 0摘要 1介绍 2预习 3治疗和指标 4深层因果模型的发展 4.1发展时间表 4.2模型分类 5典型的深层因果模型 6实验指南 6.1数据集 6.2code 6.3实验 7结论 参考 编码 1.自编码器(AE)&#xff1a; 2.去噪自编码器(DAE) 3.变分自编码器VAE 4.去耦变分自编码 文章…

复旦MBA父女“接力”,圆梦复旦|校友故事

父亲&#xff1a;钱一&#xff0c;2006级复旦MBA校友      女儿&#xff1a;钱盈&#xff0c;2017级财务管理本科&#xff0c;金融硕二年级在读      在管院的众多校友中&#xff0c;有这样一对父女&#xff1a;2006年&#xff0c;父亲钱一考上了复旦MBA&#xff0c;每…

node基于springboot 口腔卫生防护口腔牙科诊所管理系统

目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2.1 JAVA简介 4 2.2MyEclipse环境配置 4 2.3 B/S结构简介 4 2.4MySQL数据库 5 2.5 SPRINGBOOT框架 5 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.…

Hadoop配置文件常用配置-Yarn容器调度策略配置

Yarn资源调度 当同时向Yarn集群提交多个Job任务时&#xff0c;Yarn可以对任务进行资源&#xff08;CPU、MEMORY&#xff09;隔离。 容器调度策略是Yarn默认的调度策略&#xff0c;容器调度策略把整个集群资源划分成队列来管理&#xff0c;默认有一个root根队列&#xff0c;下…

聚类-理论补充

目录 一。聚类的定义 二。相似度/距离计算方法总结 1.闵可夫斯基距离Minkowski/欧式距离 2.杰卡德相似系数(Jaccard) 3.余弦相似度(cosine similarity) 4.Pearson相似系数 5.相对熵(K-L距离) 6.Hellinger距离 三。聚类的基本思想 四。k-Means算法 五。对k-Means的思…

图像显著性目标检测

一、概述 1、定义 图像显著性检测(Saliency Detection,SD)&#xff0c; 指通过智能算法模拟人的视觉系统特点&#xff0c;预测人类的视觉凝视点和眼动&#xff0c;提取图像中的显著区域(即人类感兴趣的区域)&#xff0c;可以广泛用于目标识别、图像编辑以及图像检索等领域&am…

从0到1一步一步玩转openEuler--19 openEuler 管理服务-特性说明

文章目录19 管理服务-特性说明19.1 更快的启动速度19.2 提供按需启动能力19.3 采用cgroup特性跟踪和管理进程的生命周期19.4 启动挂载点和自动挂载的管理19.5 实现事务性依赖关系管理19.6 与SysV初始化脚本兼容19.7 能够对系统进行快照和恢复19 管理服务-特性说明 19.1 更快的…

结合实例,直观理解正态分布、卡方分布、t分布、F分布和对应的Z检验、卡方检验、t检验、F检验

1 正态分布与Z检验 1.1 理论 Z检验的目的是为了验证&#xff1a;已知一个总体服从均值&#xff0c;方差的正态分布&#xff0c;现在有一些样本&#xff0c;这些样本所代表的总体的均值是否为。 则构建一个统计量Z&#xff0c; &#xff08;1&#xff09; 式中&#xff0c;为…

2023第10届生物发酵展3月30-4月1号山东济南开展,参观路线来了

2023第10届生物发酵展3月30-4月1号山东济南开展&#xff0c;参观路线来了&#xff01;展会时间&#xff1a;2023年3月30日-4月1日展馆地址&#xff1a;山东国际会展中心&#xff08;济南市槐荫区日照路1号&#xff09;展馆&#xff1a;4号馆、5号馆BIO CHINA生物发酵展&#xf…

Python|每日一练|栈|递归|散列表|数组|回溯|单选记录:重排链表|编写Python程序实现素数处理的功能| 全排列

1、重排链表&#xff08;栈&#xff0c;递归&#xff09; 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln-1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → … 不能只是单纯的改变节点内…

vue中debug调试node_modules的代码

适用于想调试webpack-dev-server&#xff08;第三方模块&#xff09;里的代码&#xff0c;在代码里打印console.log无效的情况。 我用的idea&#xff0c;配置如下&#xff1a; 一、idea配置vue项目启动 1、 主入口js配置&#xff1a;node_modules\vue\cli-service\bin\vue-c…

wine学习笔记

目前 wine 版本为较为稳定的 8.0 版本&#xff0c;本文也是重点围绕 wine 8.0 安装、使用以及 wine 工具介绍等方面进行了学习和整理。 一、安装 wine 1. 如果你使用的是 64 位系统&#xff0c;需要先开启 32 bit 架构支持&#xff1a; $ sudo dpkg --add-architecture i386…

【Kubernetes】第四篇 - k8s 集群环境搭建

一&#xff0c;前言 前两篇&#xff0c;购买了 3 台阿里云服务器并完成了 ci-server 构建服务器的环境安装与配置&#xff1b; 三台服务器规划如下&#xff1a; 服务配置内网IP外网IP说明ci-server2c4g172.17.178.104182.92.4.158Jenkins Nexus Dockerk8s-master2c4g172.1…

Visual Studio 高级调试-Dump分析

Dumpdump指转储&#xff0c;一般用来创建进程快照。它可以在不停止应用的情况下&#xff0c;直接将模块列表、线程列表、堆栈信息、异常信息、句柄信息等所有内存信息保存下来&#xff0c;帮助开发者分析生产环境问题等。这篇博客主要介绍dotnet-dump的使用以及如何在Visual St…