UNPKG

reecho

Version:

Reecho 是一款基于依赖收集的MVVM框架,它具有以下特点 - 声明式数据: 基于proxy的依赖收集 - 使用函数定义组件,但组件不会如React一样重复执行造成心智负担 - 读写分离,读取状态和更改状态统一使用函数,避免vue3的ref一样有时需要`xxx.value`有时不需要的不一致性 - 使用TS编写,类型友好

74 lines (63 loc) 1.74 kB
import { hasChanged, isObject, isSymbol, isArray, isIntegerKey, hasOwn, } from "../shared/index"; import { track, trigger } from "./effect"; import { TrackOpTypes, TriggerOpTypes } from "./operations"; const mutableHandlers = { get: (target: object, key: string | symbol, receiver: object) => { const res = Reflect.get(target, key, receiver); if (isSymbol(key)) { return res; } track(target, TrackOpTypes.GET, key); // 懒递归,触发相应get才会生成proxy if (isObject(res)) { reactive(res); } return res; }, set: ( target: object, key: string | symbol, value: any, receiver: object ): boolean => { const oldValue = target[key]; // 判断对数组/对象的操作是新增还是删除 // 通过push pop splice等方法改变数组也可以判断 const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key); const res = Reflect.set(target, key, value, receiver); if (!hadKey) { // 新增属性 trigger(target, TriggerOpTypes.ADD, key, value); } else if (hasChanged(value, oldValue)) { // 修改属性 trigger(target, TriggerOpTypes.SET, key, value, oldValue); } return res; }, }; export function reactive<T extends object>(target: T): T { return createReactiveObject<T>(target, mutableHandlers); } const proxyMap = new WeakMap(); function createReactiveObject<T extends object>(target: T, handlers): T { if (!isObject(target)) { return; } let proxy = proxyMap.get(target); if (proxy) { return proxy; } proxy = new Proxy(target, handlers); proxyMap.set(target, proxy); return proxy; }