0

0

vue3响应式实现readonly的方法是什么

WBOY

WBOY

发布时间:2023-05-20 22:19:22

|

1731人浏览过

|

来源于亿速云

转载

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 这部分也理应可以通过工厂函数创造出来。

Mulan AI
Mulan AI

画布式AI视频创作平台,轻松制作爆款视频

下载

立即学习前端免费学习笔记(深入)”;

我们先抽出一个公共的文件 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
) {
  return new Proxy(target, baseHandlers);
}
export function reactive(target) {
  return createReactiveObject(target, mutableHandler);
}
export function readonly(target) {
  return createReactiveObject(target, readonlyHandler);
}

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

42

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

46

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

202

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

341

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

16

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

100

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

73

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

75

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

67

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.5万人学习

Vue3.x 核心篇--十天技能课堂
Vue3.x 核心篇--十天技能课堂

共30课时 | 1.5万人学习

Vue3.x新特性篇--十天基础课堂
Vue3.x新特性篇--十天基础课堂

共20课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号