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

2023-11-11

【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功能》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Vue3源码】第四章 实现isReadonly和isReactive 的相关文章

随机推荐

  • IDEA 查找第三方jar里的内容

    1 Find in Path Edit gt Find gt Find in Path Scope gt Project and Libraries 说明 maven工程 貌似要下载jar source才行 2 double shift 这
  • MySQL--Group by分组与count计数(进阶)

    MySQL Group by分组与count计数 进阶 1 Group by语法 2 创建表格 3 题目代码部分 4 文末彩蛋 开心一刻 更多关于数据库知识请加关注哟 若需联系和想安装MySQL请加博主 QQ 3327908431 微信 Z
  • 具有对称性质的单参数混沌镜像系统的切换控制

    近年来 混沌已经应用到许多工程领域 例如 信息科学 复杂神经网络 信号处理 通信保密等 因此 许多学者一直探索新的混沌动力学 一些简单的光滑三维二次连续自治系统能生成混沌 1994年 Sportt提出了19个简单的混沌系统 每个系统仅有5项
  • 写一段ocr文字识别的具体实现代码

    OCR文字识别的具体实现代码如下 import cv2 读取图片 img cv2 imread example png 将图片转换为灰度图 gray cv2 cvtColor img cv2 COLOR BGR2GRAY 用Threshol
  • 串——顺序结构

    include
  • Unleashing the Power of Graph Learning through LLM-based Autonomous Agents

    本文是LLM系列文章 针对 Unleashing the Power of Graph Learning through LLM based Autonomous Agents 的翻译 通过基于LLM的自动Agent释放图学习的力量 摘要
  • mysql.的常用命令

    常用功能命令 1 导出整个数据库 1mysqldump u 用户名 p default character set latin1 数据库名 导出的文件名 数据库默认编码是latin1 23mysqldump u wcnc p smgp ap
  • LeetCode题目笔记——1566. 重复至少 K 次且长度为 M 的模式

    文章目录 题目描述 题目难度 简单 方法一 模拟 代码 C 总结 题目描述 给你一个正整数数组 arr 请你找出一个长度为 m 且在数组中至少重复 k 次的模式 模式 是由一个或多个值组成的子数组 连续的子序列 连续 重复多次但 不重叠 模
  • 数据结构学习——链表(C语言版)

    数据结构学习 链表的简单解析 一 何为链表 1 概念 2 特点 二 链表的简单实现 1 头插法 2 尾插法 3 模拟学生管理系统 一 何为链表 1 概念 链表 Linked list 是一种常见的基础数据结构 是一种线性表 但是并不会按线性
  • 公司新招了几个00后,我愿称之为卷王之王

    前几天我们公司一下子也来了几个新人 这些年轻人是真能熬啊 本来我们几个老油子都是每天稍微加会班就打算走了 这几个新人一直不走 搞得我们也不好走 2023年秋招就要开始了 最近内卷严重 各种跳槽裁员 相信很多小伙伴也在准备今年的金九银十的面试
  • java spring boot 判断用户、客户端是移动端,还是pc端

    一 设计流程 一 创建一个API 用这个API的地址 生成二维码图片 这个图片给用户扫的 二 创建二维码链接信息 例 安卓跳转到baidu com ios跳转到taobao com 三 后端系统在用户扫描后 判断用户系统 并跳转到相应地址
  • Python实现删除某列中含有空值的行

    客户需求 查看销售人员不为空值的行 数据存储情况如图 代码实现 import pandas as pd data pd read excel test xlsx sheet name Sheet1 datanota data data 销售
  • TensorFlow:常用函数介绍

    学习网址 Tensorflow中文社区 http www tensorfly cn 一 tensorflow框架笔记 1 Variable 一个Variable代表一个可修改的张量 存在在TensorFlow的用于描述交互性操作的图中 它们
  • C程序头文件注释格式

    Copyright C 2010 2011 Your Company FileName 文件名 Author 作者 Version 版本 Date 完成日期 Description 用于主要说明此程序文件完成的主要功能 与其他模块或函数的接
  • 蓝牙设备上电提示Failed to set power on: org.bluez.Error.Blocked

    NEW Controller 74 2F 68 6A 37 44 moon 0 default NEW Device 00 07 61 76 8E 78 Logitech diNovo Edge Agent registered bluet
  • 03. 微信公众号消息接收、事件推送与响应处理

    1 消息接收 官方文档 当普通微信用户向公众账号发消息时 微信服务器将POST消息的XML数据包到开发者填写的URL上 gt 接口配置信息的URL 即开发时 接收信息的接口的访问路径与微信接入的URL一致 但为 POST 请求 请求参数 依
  • 计算机毕业设计Java的工资管理系统(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Java的工资管理系统 源码 系统 mysql数据库 lw文档 计算机毕业设计Java的工资管理系统 源码 系统 mysql数据库 lw文档 本源码技术栈 项目架构 B S架构 开发语言 Java语言 开发软件 idea ec
  • QA 如何打造自身的核心竞争力?

    转载自微服务质量保障 20 讲嘉木老师 怎样理解 核心竞争力 在讲解竞争力之前先看下什么是能力 能力是指一个人完成一个目标或者任务所体现出来的素质 如技能 知识 经验以及行为等 解释中暗含了 能力是一个绝对值 正数 的意思 显得比较学术 而
  • 360度全景标定方法_一种360度全视角鸟瞰全景行车辅助标定方法与流程

    技术领域本发明涉及辅助驾驶领域 具体地说是一种360度全视角鸟瞰全景行车辅助标定方法 背景技术 随着图像和计算机视觉技术的快速发展 越来越多的技术被应用到汽车电子领域 传统的基于图像倒车影像系统在车尾安装摄像头 只能覆盖车尾周围有限的区域
  • 【Vue3源码】第四章 实现isReadonly和isReactive

    Vue3源码 第四章 实现isReadonly和isReactive 前言 上一章节我们实现readonly API 并且优化之前写的reactive API 这一章我们实现isReadonly和isReactive两个API 1 实现is