实现shallowReadonly和isProxy功能示例详解

目录
  • 一、实现shallowReadonly
    • (一)单元测试
    • (二)代码实现
    • (三)额外的单测
  • 二、实现isProxy
    • (一)单元测试
    • (二)代码实现

一、实现shallowReadonly

(一)单元测试

// src/reactivity/tests/shallowReadonly.spec.ts
import { isReadonly, shallowReadonly } from '../reactive';
describe('shallowReadonly', () => {
  it('should not make non-reactive properties reactive', () => {
    const props = shallowReadonly({ n: { foo: 1 } });
    expect(isReadonly(props)).toBe(true);
    expect(isReadonly(props.n)).toBe(false);
  });
});

shallowReadonly,浅层只读,从单测也很容易看出来。一般的应用场景,可能就是用于项目的优化,避免将深层全部转为readonly。

(二)代码实现

// src/reactivity/reactive.ts
import { mutableHandlers, readonlyHandlers, shallowReadonlyHandlers } from './baseHandlers';
export function shallowReadonly(target) {
  return createReactiveObject(target, shallowReadonlyHandlers);
}
// src/reactivity/baseHandlers.ts
import { isObject, extend } from '../shared';
function createGetter(isReadonly = false, shallow = false) {
  return function get(target, key) {
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly;
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly;
    }
    const res = Reflect.get(target, key);
    // + shallow,直接返回,深层不转响应式
    if (shallow) {
      return res;
    }
    if (isObject(res)) {
      return isReadonly ? readonly(res) : reactive(res);
    }
    if (!isReadonly) {
      track(target, key);
    }
    return res;
  };
}
const shallowReadonlyGet = createGetter(true, true);
// + 其实可见shallowReadonly的set逻辑同readonly,所以从readonly那继承过来,然后改写get逻辑即可
export const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
  get: shallowReadonlyGet
});

最基本的逻辑,这就完成了,单测一下。

(三)额外的单测

当然为了严谨一些,我们还是测试一下,浅层和深层的set操作的结果,是否是我们期望的。

it('should make root level properties readonly', () => {
  console.warn = jest.fn();
  const user = shallowReadonly({ age: 10 });
  user.age = 11;
  expect(console.warn).toBeCalled();
});
it('should NOT make nested properties readonly', () => {
  console.warn = jest.fn();
  const props = shallowReadonly({ n: { foo: 1 } });
  props.n.foo = 2;
  expect(props.n.foo).toBe(2);
  expect(console.warn).not.toBeCalled();
});

二、实现isProxy

这里贴上官网对isProxy的描述。

Checks if an object is a proxy created by reactive or readonly

(一)单元测试

我们只需要在之前的用例中补充断言即可。

// src/reactivity/tests/reactive.spec.ts
import { reactive, isReactive, isProxy } from '../reactive';
// reactive -> happy path
expect(isProxy(observed)).toBe(true);
// src/reactivity/tests/readonly.spec.ts
import { readonly, isReadonly, isProxy } from '../reactive';
// readonly -> happy path
expect(isProxy(wrapped)).toBe(true);

(二)代码实现

其实实现起来,我们只要复用之前的isReactiveisProxy即可。

// src/reactivity/reactive.ts
export function isProxy(value) {
  return isReactive(value) || isReadonly(value);
}

以上就是实现shallowReadonly和isProxy功能示例详解的详细内容,更多关于shallowReadonly isProxy功能的资料请关注我们其它相关文章!

(0)

相关推荐

  • Vue3中reactive与ref函数使用场景

    目录 前言 简单了解 ref & reactive reactive ref reactive 能做的 ref 也能做,并且还是用 reactive 做的 ref 能做,但是 reactive 不能做 总结 前言 如果你使用过 Vue3,你知道的,在 Vue3 中有两个非常常用的响应式 API:reactive 和 ref.它们会把我们想要追踪的数据变成响应式. 而且我们在使用时一直被告知 ref 用于创建基础类型的响应式,也可以创建引用类型的响应式.而对于引用类型,底层也是转换为 reacti

  • Vue3系列之effect和ReactiveEffect track trigger源码解析

    目录 引言 一.ReactiveEffect 1. 相关的全局变量 2. class 声明 3. cleanupEffect 二.effect 函数 1. 相关ts类型 2. 函数声明 3. stop函数 三.track 依赖收集 1. track 2. createDep 3. trackEffects 4. 小结 四.trigger 1. triggerEffect 2. triggerEffects 3. trigger 五.小结 1. 依赖收集 2. 触发更新 引言 介绍几个API的时候

  • reactive readonly嵌套对象转换功能实现详解

    目录 一.单元测试 reactive readonly 二.代码实现 一.单元测试 reactive // src/reactivity/tests/reactive.spec.ts it('nested reactive', () => { const original = { nested: { foo: 1 }, array: [{ bar: 2 }] }; const observed = reactive(original); expect(isReactive(observed.ne

  • Vue3 源码分析reactive readonly实例

    目录 引言 一.reactive 和 readonly 1. reactive相关类型 2. 相关全局变量与方法 3. reactive函数 4. 造物主createReactiveObject 5. shallowReactive.readonly和shallowReadonly 二.对应的 Handlers 1. baseHandlers 1.1 reactive 1.2 readonly 1.3 shallowReactive 1.4 shallowReadonly 2. cellecti

  • Reactive Programming入门概念详解

    目录 正文 Reactive Programming Reactive Streams Spring Reactor Reactive Streams.Reactor和WebFlux 区别? 正文 为了应对高并发环境下的服务端编程,xx提出了一个实现异步编程的方案 -Reactive Programming,中文名称反应式编程.反应式编程(reactive programming)并不是一个新的概念,也不是一个新的技术,很早之前就被提出来了. 先从几个概念入门说起: Reactive Progr

  • 实现shallowReadonly和isProxy功能示例详解

    目录 一.实现shallowReadonly (一)单元测试 (二)代码实现 (三)额外的单测 二.实现isProxy (一)单元测试 (二)代码实现 一.实现shallowReadonly (一)单元测试 // src/reactivity/tests/shallowReadonly.spec.ts import { isReadonly, shallowReadonly } from '../reactive'; describe('shallowReadonly', () => { it(

  • RocketMQ实现随缘分BUG小功能示例详解

    目录 正文 实现过程 生产者: 正文 以前公司的产品已经上线20多年了,主要是维护,也就是改bug.每周我们Team会从Jira上拿我们可以改的bug,因为每个团队负责的业务范围不一样,我们团队只能改我们自己业务范围的.这样每周大概有20个左右的新bug,假如团队一共10个人,那么均分就是每人两个,改完下班. 但是这BUG肯定有难有简单,大家肯定都愿意改简单的,在家办公,任务量完了不就等于放假么.开始是自己给自己抢,就忒卷,是欧美项目,所以客服晚上报出来的bug多.有的哥们早上5点起来看有没有新

  • vue3使用自定义指令实现el dialog拖拽功能示例详解

    目录 实现el-dialog的拖拽功能 通过自定义指令实现拖拽功能 实现拖拽功能 使用方式 实现el-dialog的拖拽功能 这里指的是 element-plus 的el-dialog组件,一开始该组件并没有实现拖拽的功能,当然现在可以通过设置属性的方式实现拖拽. 自带的拖拽功能非常严谨,拖拽时判断是否拖拽出窗口,如果出去了会阻止拖拽. 如果自带的拖拽功能可以满足需求的话,可以跳过本文. 通过自定义指令实现拖拽功能 因为要自己操作dom(设置事件),所以感觉还是使用自定义指令更直接一些,而且对原

  • 使用纯JavaScript封装一个消息提示条功能示例详解

    目录 介绍 思路&布局 操作逻辑 完整代码 介绍 一个类似Element UI.Ant-Design UI等 UI 框架的消息提示功能,方便在任何网页环境中直接调用函数使用:区别在不依赖 js 及 css 引用,而是使用纯 js 进行封装实现,代码更精简,同时保持和 UI 框架一样的视觉效果(可自行修改成自己喜欢的样式) 代码仓库 在线预览效果(点击[登录].[点击复制]按钮时触发提示效果) 思路&布局 先来写单个提示条,并实现想要的过渡效果,最后再用逻辑操作输出节点即可:这里不需要父节点

  • react echarts tree树图搜索展开功能示例详解

    目录 前言 最终效果 版本信息 核心功能: 关键思路: 附上代码 数据data.js 功能: TreeUtils 总结: 前言 umi+antd-admin 框架中使用类组件+antd结合echarts完成树图数据展示和搜索展开功能 最终效果 版本信息 "antd": "3.24.2", "umi": "^2.7.7", "echarts": "^4.4.0", "echart

  • Springboot Vue实现单点登陆功能示例详解

    目录 正文 简单上个图 先分析下登陆要做啥 怎么落实? 上代码 接口: token生成部分 刷新token 验证token 正文 登陆是系统最基础的功能之一.这么长时间了,一直在写业务,这个基础功能反而没怎么好好研究,都忘差不多了.今天没事儿就来撸一下. 以目前在接触和学习的一个开源系统为例,来分析一下登陆该怎么做.代码的话我就直接CV了. 简单上个图 (有水印.因为穷所以没开会员) 先分析下登陆要做啥 首先,搞清楚要做什么. 登陆了,系统就知道这是谁,他有什么权限,可以给他开放些什么业务功能,

  • iReport使用指南及常见功能示例详解

    目录 报表结构 数据源 示例 3.1 简单示例 3.2 分组示例 3.3 子表方式分组查看 3.4 图表示例 3.4.1 饼图 3.4.2 柱状图 3.5交叉报表 在使用ireport的过程中,因为各种功能都要百度,但是大家使用的例子又千差万别让人很苦恼,所以用一个简单例子贯穿的展示一下ireport的常见功能. 我使用的是iReport 3.5.1,使用的示例数据表如图: sales表:(人名.大致结构来自帆软电子文档,如有雷同,无意冒犯) sellers表: 下面开始介绍: 报表结构 左边是

  • laravel如何开启跨域功能示例详解

    前言 本文主要给大家介绍了关于laravel开启跨域功能的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 跨域的请求 出于安全性的原因,浏览器会限制 Script 中的跨域请求.由于 XMLHttpRequest 遵循同源策略,所有使用 XMLHttpRequest 构造 HTTP 请求的应用只能访问自己的域名,如果需要构造跨域的请求,那么开发者需要配合浏览器做出一些允许跨域的配置. W3C 应用工作组推荐了一种跨资源共享的机制,这种机制让 Web 应用服务器能支持跨

  • vue+element实现下拉菜单并带本地搜索功能示例详解

    需求: 后台返回数组对像,前端组合成数组,根据name组合成一个个数组并把后台返回的值当成一个children推入数组,在数组中自定义属性备份数据防止搜索的时候改变原数组使得数组无法回退 这里是用的vuex存储,因为多个页面使用同一个接口;所以没必要重复请请求 src\store\module\metadata.js /* * @Author: your name * @Date: 2021-09-02 15:46:45 * @LastEditTime: 2021-09-16 17:39:53

  • JavaScript中的ajax功能的概念和示例详解

    AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML). 个人理解:ajax就是无刷新提交,然后得到返回内容. 对应的不使用ajax时的传统网页如果需要更新内容(或用php做处理时),必须重载整个网页页面. 示例: html代码如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>

随机推荐