vue3响应式实现readonly从零开始教程

 更新时间:2023年03月06日 16:22:25   作者:Yuin316  
这篇文章主要为大家介绍了vue3响应式实现readonly从零开始教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

前面的章节我们把 effect 部分大致讲完了,这部分我们来讲 readonly以及重构一下reactive

readonly的实现

it("happy path", () => {
    console.warn = vi.fn();
    const original = {
      foo: 1,
    };
    const observed = readonly({
      foo: 1,
    });
    expect(original).not.toBe(observed);
    expect(observed.foo).toBe(1);
    //  set不起作用
    observed.foo = 2; 
    expect(observed.foo).toBe(1);
    //  当被set的时候,发出一个警告
    expect(console.warn).toBeCalled();
  });

其实与我们之前实现 reactive 十分的类似,区别只不过是set 的时候不要触发trigger,而是警告。当然既然是不会被改变的,track 也是不必要的。

export function readonly(raw) { 
    return new Proxy(raw, { 
        get(target, key) { 
            const res = Reflect.get(target, key); 
            return res; 
        }, 
        set(target, key, newValue, receiver) {
            console.warn(
              `property: ${String(key)} can't be set, beacase ${target} is readonly.`
            );
            return true;
      },
    }); 
}
export function reactive(raw) { 
    return new Proxy(raw, { 
        get(target, key) { 
            const res = Reflect.get(target, key); 
            // 依赖收集 
            track(target, key); 
            return res; 
        }, 
        set(target, key, value) { 
            const res = Reflect.set(target, key, value); 
            // 触发依赖 
            trigger(target, key); 
            return res; 
        }, 
    }); 
}

重构

可以看到,readonlyreactive 实现其实很类似,那我们可以重构一下,增强后续的拓展性。

至于我说的类似,指的是 new Proxy(target, handlers) 中的handlers(处理器对象)中的一些traps(捕获器)。即get, set 这些方法。

我们可以通过工厂函数来创建那些traps函数,来简化我们的代码,提高可维护性。

另外,我们假定traps可以有工厂可以生产了,即handlers这部分相当于被定下来了,new Proxy 这部分也理应可以通过工厂函数创造出来。

我们先抽出一个公共的文件 baseHandler.ts

//  baseHanlder.ts
import { track, trigger } from "./effect";
//  get的工厂函数
function createGetter(isReadonly = false) {
  return function get(target, key) {
    const res = Reflect.get(target, key);
    if (!isReadonly) {
      track(target, key);
    }
    return res;
  };
}
function createSetter() {
  return function set(target, key, newValue, receiver) {
    const res = Reflect.set(target, key, newValue, receiver);
    trigger(target, key, type, newValue);
    return res;
  };
}
export const mutableHandler = {
  get: createGetter(),
  set: createSetter(),
};
export const readonlyHandler = {
  get: createGetter(),
  set(target, key, newValue, receiver) {
    console.warn(
      `property: ${String(key)} can't be set, beacase ${target} is readonly.`
    );
    return true;
};

然后是我们的reactive.ts

//  reactive.ts
import {
  mutableHandler,
  readonlyHandler,
} from "./baseHandlers";
//  proxy的工厂函数
function createReactiveObject(
  target,
  baseHandlers: ProxyHandler<any>
) {
  return new Proxy(target, baseHandlers);
}
export function reactive(target) {
  return createReactiveObject(target, mutableHandler);
}
export function readonly(target) {
  return createReactiveObject(target, readonlyHandler);
}

结束

本篇幅比较短小,但是算是为后续打下了一些基础吧。因为笔者发现边学边写总结文章速度很慢,然后写完 effect 那几篇之后就开始直接一路往下学,中途虽然有提交git,但是没有打tag的习惯,搞的现在回来来写文章有点无从下手。

不过最近应该快把diff那部分搞定了,到时候应该会加快速度更新,更多关于vue3响应式readonly的资料请关注脚本之家其它相关文章!

相关文章

  • vue全家桶-vuex深入讲解

    vue全家桶-vuex深入讲解

    这篇文章主要介绍了vue全家桶-vuex深入讲解,文章内容详细,简单易懂,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2023-01-01
  • vue中的v-touch事件用法说明

    vue中的v-touch事件用法说明

    这篇文章主要介绍了vue中的v-touch事件用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • vue项目中实现缓存的最佳方案详解

    vue项目中实现缓存的最佳方案详解

    这篇文章主要给大家介绍了关于vue项目中实现缓存的最佳方案,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • 快速了解Vue父子组件传值以及父调子方法、子调父方法

    快速了解Vue父子组件传值以及父调子方法、子调父方法

    这篇文章主要介绍了Vue父子组件传值以及父调子方法、子调父方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法

    SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法

    这篇文章主要介绍了SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题,需要的朋友可以参考下
    2018-01-01
  • vue使用xe-utils函数库的具体方法

    vue使用xe-utils函数库的具体方法

    这篇文章主要介绍了vue使用xe-utils函数库的具体方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • vue与vue-i18n结合实现后台数据的多语言切换方法

    vue与vue-i18n结合实现后台数据的多语言切换方法

    下面小编就为大家分享一篇vue与vue-i18n结合实现后台数据的多语言切换方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue-cli 3.x配置跨域代理的实现方法

    vue-cli 3.x配置跨域代理的实现方法

    这篇文章主要介绍了vue-cli 3.x配置跨域代理的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 解决vue表单为空也能提交的问题

    解决vue表单为空也能提交的问题

    这篇文章主要介绍了解决vue表单为空也能提交的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Vue.js双向绑定实现原理详解

    Vue.js双向绑定实现原理详解

    这篇文章主要为大家详细介绍了Vue.js双向绑定实现原理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12

最新评论