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.nested)).toBe(true);
  expect(isReactive(observed.array)).toBe(true);
  expect(isReactive(observed.array[0])).toBe(true);
});

readonly

it('nested readonly', () => {
  const original = { foo: 1, bar: { baz: 2 } };
  const wrapped = readonly(original);
  expect(isReadonly(wrapped)).toBe(true);
  expect(isReadonly(wrapped.bar)).toBe(true);
});

二、代码实现

为什么嵌套的深层对象没有转换成reactivereadonly呢?

因为Proxy劫持的是对象本身,并不能劫持子对象的变化。

其实通过单测可以看出,我们只需要将reactive嵌套的里层对象也转换成reactive,将readonly嵌套的里层对象也转换成readonly

那只需要在get中,返回res的时候,将res转换成相应的代理就可以了。

function createGetter(isReadonly = false) {
  return function get(target, key) {
    const res = Reflect.get(target, key);
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly;
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly;
    }
    if (isObject(res)) {
      return isReadonly ? readonly(res) : reactive(res);
    }
    if (!isReadonly) {
      track(target, key);
    }
    return res;
  };
}

跑一下完整的单测结果看下:

ps: 其实这里需要注意的一点就是,在get中处理嵌套转换,我们只有在用到这个子对象的时候,才会将这个子对象 转换成响应时代理,避免了不必要的性能浪费。对比vue2的递归遍历defineProperty来说,也是一个优化的地方。

以上就是reactive readonly嵌套对象转换功能实现详解的详细内容,更多关于reactive readonly嵌套对象转换的资料请关注我们其它相关文章!

(0)

相关推荐

  • react-router 重新加回跳转拦截功能详解

    目录 前言 事件经过 v6 之前的版本如何拦截 v6.7.0+ 如何拦截 吐槽 前言 路由的跳转拦截,在一些表单页中尤为常见.场景:用户输入了一些信息后但未提交,为了防止用户误点击某个跳转链接导致所填的表单信息丢失,跳转之前会弹出一个提示,如 “信息未提交,请确认是否离开” 等字样. 事件经过 在 react-router v6 之前有提供一个 <Prompt /> 组件来拦截路由的跳转.而在 v6 中却不支持此功能了!社区一片哀嚎,经查在 v6 实验阶段是有此功能的,但在 v6.0.0 be

  • React 实现具备吸顶和吸底功能组件实例

    目录 背景 实现 结语 背景 现在手机应用经常有这样一个场景: 页面上有一个导航,导航位置在页面中间位置,当页面顶部滚动到导航位置时,导航自动吸顶,页面继续往下滚动时,它就一直在页面视窗顶部显示,当往上滚动时,经过最初位置时,导航自动复原,不再吸顶. 效果就如京东超市首页的导航栏一样: 下面我们就来具体实现这样一个 React 组件,实现后还会再扩展延伸一下 吸底 功能,因为 吸底 场景也不少. 具体要求: 需要可以设置是 吸顶 还是 吸底. 吸顶 可以设置距离视窗顶部的位置,吸顶 可以设置距离

  • React Native 中实现倒计时功能

    目录 正文 首次实现 最终实现 示例 正文 在 React Native,该如何实现一个倒计时功能呢? 首次实现 表面看来很简单,譬如像下面这样: const timer = useRef<ReturnType<typeof setInterval> | null>(null) const [count, setCount] = useState(0) const start = () => { setCount(10) timer.current = setInterval

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

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

  • 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

  • Java编程思想对象的容纳实例详解

    Java提供了容纳对象(或者对象的句柄)的多种方式,接下来我们具体看看都有哪些方式. 有两方面的问题将数组与其他集合类型区分开来:效率和类型.对于Java来说,为保存和访问一系列对象(实际是对象的句柄)数组,最有效的方法莫过于数组.数组实际代表一个简单的线性序列,它使得元素的访问速度非常快,但我们却要为这种速度付出代价:创建一个数组对象时,它的大小是固定的,而且不可在那个数组对象的"存在时间"内发生改变.可创建特定大小的一个数组,然后假如用光了存储空间,就再创建一个新数组,将所有句柄从

  • 使用Vue-Router 2实现路由功能实例详解

    vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来.传统的页面应用,是用一些超链接来实现页面切换和跳转的.在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换. 注意:vue-router 2只适用于Vue2.x版本,下面我们是基于vue2.0讲的如何使用vue-router 2实现路由功能. 推荐使用npm安装. npm install v

  • 用原生 JS 实现 innerHTML 功能实例详解

    都知道浏览器和服务端是通过 HTTP 协议进行数据传输的,而 HTTP 协议又是纯文本协议,那么浏览器在得到服务端传输过来的 HTML 字符串,是如何解析成真实的 DOM 元素的呢,也就是我们常说的生成 DOM Tree,最近了解到状态机这样一个概念,于是就萌生一个想法,实现一个 innerHTML 功能的函数,也算是小小的实践一下. 函数原型 我们实现一个如下的函数,参数是 DOM 元素和 HTML 字符串,将 HTML 字符串转换成真实的 DOM 元素且 append 在参数一传入的 DOM

  • Spring cloud alibaba之Gateway网关功能特征详解

    目录 1.网关简介 2.什么是spring cloud gateway 2.1核心概念 3.Spring Cloud Gateway快速开始 5.路由断言工厂(Route Predicate Factories)配置 6.自定义路由断言工厂 7.Filter过滤器 8.自定义过滤器 9.自定义全局过滤器(Global Filters) 10.Gateway跨域配置(CORS Configuration) 11.Gateway整合Sentinel进行流控 12.流控配置说明 13.自定义重写流控返

  • vue3响应式Object代理对象的读取示例详解

    目录 正文 读取属性 xx in obj for ... in 正文 从这一章开始,作者将更新深入的讲解响应式,尤其是vue3响应式的具体的实现.其实在前面一章,如果你仔细阅读,你是可以实现一个简单的响应式函数的,类似于@vue/reactive,当然那只是个demo,是个玩具,我能不能在生产环境上去使用的,它差了太多功能和边界条件. 现在,我们才是真正的深入@vue/reactive. 在vue中,obj.a是一个读取操作,但是仔细想来,读取这个操作很宽泛. obj.a // 访问一个属性 '

  • Go开发Gin项目添加jwt功能实例详解

    目录 啥是JWT 为什么要用在你的Gin中使用JWT JWT的基本原理 JWT TOKEN怎么组成 Header Base64URL Payload Signature 解密过程 一些特点(优点和缺点) GIN整合JWT 编写jwtutil GenToken方法 ParseToken方法 编写中间件 使用中间件 测试 其他 啥是JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场

  • vue3调度器effect的scheduler功能实现详解

    目录 一.调度执行 二.单元测试 三.代码实现 四.回归实现 五.结语 一.调度执行 说到scheduler,也就是vue3的调度器,可能大家还不是特别明白调度器的是什么,先大概介绍一下. 可调度性是响应式系统非常重要的特性.首先我们要明确什么是可调度性.所谓可调度性,指的是当trigger 动作触发副作用函数重新执行时,有能力决定副作用函数执行的时机.次数以及方式. 有了调度函数,我们在trigger函数中触发副作用函数重新执行时,就可以直接调用用户传递的调度器函数,从而把控制权交给用户. 举

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

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

  • Laravel 5.5 的自定义验证对象/类示例代码详解

    Laravel 5.5 将提供一个全新的自定义验证规则的对象,以作为原来的 Validator::extend 方法的替代. Laravel 5.5 将提供一个全新的自定义验证规则的对象,以作为原来的 Validator::extend 方法的替代..很多时候我们会直接用正则表达式来处理这种特殊的验证,也有时候我们会选择用 Validator::extend 来扩展一个自定义的规则.但在 Laravel 5.5 版本中,我们有了新的手段,只要定义一个实现 Illuminate\Contracts

随机推荐