UNPKG

reecho

Version:

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

89 lines (72 loc) 2.1 kB
import { isArray } from "./../shared/index"; import { isObject, hasChanged } from "../shared/index"; import { reactive } from "./reactive"; import { track, trigger } from "./effect"; import { TriggerOpTypes, TrackOpTypes } from "./operations"; export interface Ref<T = any> { value: T; _shallow?: boolean; } function convert<T extends unknown>(value: T) { return isObject(value) ? reactive(value as any) : value; } class RefImpl<T> { public _value: T; public _isRef: boolean = true; constructor(private rawValue: T, public readonly shallow: boolean) { // shallow时只代理第一层 this._value = shallow ? rawValue : convert<T>(rawValue); } get value() { track(this, TrackOpTypes.GET, "value"); return this._value; } set value(newVal) { if (hasChanged(newVal, this.rawValue)) { this.rawValue = newVal; this._value = newVal; trigger(this, TriggerOpTypes.SET, "value", newVal); } } } function createRef(rawValue: unknown, shallow: boolean): Ref { if (isRef(rawValue)) { return rawValue; } return new RefImpl(rawValue, shallow); } export function ref<T>(value: T): Ref<T> { return createRef(value, false); } export function shallowRef<T>(value: T): Ref<T> { return createRef(value, true); } export function isRef(target: any): target is Ref { return target && target._isRef === true; } // 非响应性代理 class ObjectRefImpl { public _isRef = true; constructor(public target, public key) {} get value() { return this.target[this.key]; } set value(newVal) { this.target[this.key] = newVal; } } export function toRef(target, key): Ref { return new ObjectRefImpl(target, key); } export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N export type ToRef<T> = IfAny<T, Ref<T>, [T] extends [Ref] ? T : Ref<T>> export type ToRefs<T = any> = { [K in keyof T]: ToRef<T[K]>; }; export function toRefs<T extends object>(object: T): ToRefs<T> { const ret: any = isArray(object) ? new Array(object.length) : {}; for (const key in object) { ret[key] = toRef(object, key); } return ret; }