UNPKG

mpstore-next

Version:

一个轻量级的状态管理库,类似于`pinia`、`vuex`,适用于微信小程序。

297 lines (293 loc) 10 kB
type AnyObject = WechatMiniprogram.IAnyObject; /** * 微信小程序页面实例 */ type PageInstance = WechatMiniprogram.Page.Instance<WithStore<WechatMiniprogram.Page.DataOption, AnyObject>, WechatMiniprogram.Page.CustomOption>; /** * 微信小程序组件实例 */ type ComponentInstance = WechatMiniprogram.Component.Instance<WithStore<WechatMiniprogram.Component.DataOption, AnyObject>, WechatMiniprogram.Component.PropertyOption, WechatMiniprogram.Component.MethodOption, WechatMiniprogram.IAnyObject>; /** * 定义一个可选的 Store 配置对象,包含 `stores` 字段。 * `stores` 字段为部分 Store 配置,用于动态定义多个模块化的 store。 * * @template S - 状态类型。 * @template G - 派生状态类型(Getters)。 * @template A - 行为类型(Actions)。 */ type TStore<S extends State = State, G extends Getters<S> = Getters<S>, A extends Actions = Actions> = Partial<{ stores: Partial<StoreConfig<S, G, A>>; }>; /** * 用于扩展组件或数据对象,使其具备与 store 交互的能力。 * 可以访问当前模块或多个模块的 `$state` 和 `$getter`。 * * @template TData - 原始数据类型。 * @template TStoreState - store 状态类型(可同时表示 state 和 getter)。 */ type WithStore<TData, TStoreState> = TData & Partial<{ /** * 当前默认 store 的状态。 */ $state: TStoreState; /** * 当前默认 store 的 getter。 */ $getter: TStoreState; }> & Partial<{ /** * 支持多个命名空间 store,每个 store 可以拥有自己的 `$state` 和 `$getter`。 */ [key: string]: Partial<{ $state: TStoreState; $getter: TStoreState; }>; }>; /** * 配置一个单独的 Store 的结构类型。 * * @template S - 状态对象的类型(State) * @template G - Getter 的类型 * @template A - Action 的类型 */ type OneStoreConfig<S, G, A> = Partial<{ /** * 需要使用的 store 实例。 */ store: Store<S, G, A>; /** * 过滤store属性,默认为不过滤 * * 用于按需导入需要的store数据, 只包含`state` 和 `getter`中属性 */ useProp: string[]; }>; /** * 多个 Store 或单个 Store 的完整配置类型。 * * @template S - 状态对象的类型(State) * @template G - Getter 的类型 * @template A - Action 的类型 */ type StoreConfig<S, G, A> = { /** * 开始命名空间的隔离 * * 适用于多个store同时使用,`usePart` 为 `true` 的时候,会使用`defineStore`所定义的`key`作为命名空间的隔离 */ usePart: boolean; /** * 过滤store属性,默认为不过滤 * * 用于按需导入需要的store数据, 只包含`state` 和 `getter`中属性 */ useProp: string[]; /** * 需要使用的 store,可以是单个 Store 实例,也可以是多个 Store 组成的数组。 */ store: Store<S, G, A> | Array<Store<S, G, A>>; /** * 多个store的配置项 * * 这个时候只会使用`config`,而`store`会被忽略 * 针对每个 store 的单独配置项数组。 * 每项可配置具体的 store 和其对应的使用属性。 */ config: Array<OneStoreConfig<S, G, A>>; }; type State = AnyObject; type Subscriber = (state: AnyObject) => void; type DeepReadonly<T> = { readonly [P in keyof T]: DeepReadonly<T[P]>; }; type ExtractGetters<G> = { readonly [K in keyof G as G[K] extends (...args: any[]) => infer R ? R extends void ? never : K : never]: G[K] extends (...args: any[]) => infer R ? R : never; }; type Getters<S> = { [K in string]: (state: DeepReadonly<S>) => unknown; }; type Actions = { [K in string]: (...args: any[]) => unknown; }; type Store<S, G, A> = S & Omit<ExtractGetters<G>, keyof S> & Readonly<A & StoreAction<S, G, A>>; type IsFunction<T> = T extends (...args: any[]) => any ? true : false; type WatchProperty<T> = IsFunction<T> extends true ? never : T; type WatchValue<T> = WatchProperty<T> | WatchProperty<T>[]; /** * 定义 store 的选项类型。 * * @template S 状态对象类型 * @template G getter 对象类型 * @template A action 对象类型 */ type DefineStoreOptions<S extends State, G extends Getters<S>, A extends Actions> = { /** * 返回状态对象的函数。 */ state: () => S; /** * getter 对象,可通过 `this` 访问状态、getter(排除状态键)和 actions。 */ getters?: G & ThisType<S & Omit<ExtractGetters<G>, keyof S> & A>; /** * action 对象,可通过 `this` 访问状态、getter(排除状态键)和 actions。 */ actions?: A & ThisType<S & Omit<ExtractGetters<G>, keyof S> & A>; }; /** * 每个 Store 实例额外扩展的方法集合。 * * @template S 状态类型 * @template G getter 类型 * @template A action 类型 */ type StoreAction<S, G, A> = { /** * 获取当前 store 的唯一 key。 */ $key: () => string; /** * 批量更新状态。 * @param partial 状态的部分字段 */ $patch: (partial: Partial<S>) => void; /** * 订阅状态变更。 * @param fn 回调函数 * @returns 取消订阅函数,返回值标记是否成功取消 */ $subscribe: (fn: Subscriber) => () => boolean; /** * 绑定状态更新逻辑,支持局部更新。 * @param fn 更新函数 * @param part 是否为局部绑定 * @returns 取消更新函数 */ $update: (fn: Subscriber, part?: boolean) => () => boolean; /** * 判断某个实例是否已绑定。 * @param instance 页面或组件实例 */ $has: (instance: PageInstance | ComponentInstance) => boolean; /** * 将状态绑定到页面或组件实例。 * @param instance 页面或组件实例 * @param part 是否局部绑定 * @param filterProps 可选字段过滤列表 */ $bind: (instance: PageInstance | ComponentInstance, part?: boolean, filterProps?: string[]) => void; /** * 解绑页面或组件实例。 * @param instance 页面或组件实例 */ $unbind: (instance: PageInstance | ComponentInstance) => void; /** * 销毁该 store 实例。 */ $dispose: () => void; /** * 重置为初始状态。 */ $reset: () => void; /** * 监听某个值的变化。 * * @template T 要监听的字段的类型 * @param source 返回要监听的值的函数 * @param cb 值变化时的回调 * @param options 配置项(是否立即触发) * @returns 停止监听的函数 */ $watch: <T = Store<S, G, A>[Exclude<keyof Store<S, G, A>, keyof (A & StoreAction<S, G, A>)>]>(source: () => WatchValue<T>, cb: (newValue: WatchValue<T>, oldValue: WatchValue<T>) => void, options?: { immediate?: boolean; }) => () => void; }; /** * 定义一个小程序组件。 * * @template TData 组件数据类型 * @template TProperty 组件属性类型 * @template TMethod 组件方法类型 * @template TCustomInstanceProperty 自定义实例属性类型 * @template TIsPage 是否是页面(默认 false) * @param options 组件配置项,支持扩展 store * @returns 微信小程序组件实例 * * @example * ```javascript * const counterStore = useCounterStore() * defineComponent({ * stores: { * store: counterStore * }, * data: { * }, * methods: { * } * }) * ``` */ declare function defineComponent<TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}, TIsPage extends boolean = false>(options: WechatMiniprogram.Component.Options<TData, TProperty, TMethod, TCustomInstanceProperty, TIsPage> & TStore): string; /** * 定义一个小程序页面。 * * @template TData 页面数据类型 * @template TCustom 自定义页面选项类型 * @param options 页面配置项,支持扩展 store * @returns 微信小程序页面实例 * * @example * ```javascript * const counterStore = useCounterStore() * definePage({ * stores: { * store: counterStore * }, * data: { * }, * }) * ``` */ declare function definePage<TData extends WechatMiniprogram.Page.DataOption, TCustom extends WechatMiniprogram.Page.CustomOption>(options: WechatMiniprogram.Page.Options<TData, TCustom> & TStore): void; /** * 定义一个新的 Store。 * * 用于创建响应式状态管理对象,支持 state、getters 和 actions, * 并提供一套生命周期管理函数(如 `$patch`, `$subscribe`, `$watch`,`$update` 等)。 * * @template S Store 的状态类型(State) * @template G Store 的 getter 类型(Getters) * @template A Store 的 action 类型(Actions) * * @param key - Store 的唯一标识符,通常用于内部存储和调试。 * @param options - 包含 `state`、`getters` 和 `actions` 的配置对象: * - `state`: 返回初始状态的函数。 * - `getters`: 可选的 getter 对象,用于派生状态。 * - `actions`: 可选的 action 对象,用于封装业务逻辑。 * * @returns 返回一个函数,调用该函数可获取该 Store 实例对象。 * Store 实例具备完整的状态读写、监听和绑定功能。 * * @example * ```javascript * const useCounterStore = defineStore('counter', { * state: () => ({ count: 0 }), * getters: { * double() { * return this.count * 2; * } * }, * actions: { * increment() { * this.count++; * } * } * }); * * const counter = useCounterStore(); * counter.increment(); * console.log(counter.double); // 输出:2 * ``` */ declare function defineStore<S extends State, G extends Getters<S>, A extends Actions>(key: string, options: DefineStoreOptions<S, G, A>): () => Store<S, G, A>; export { defineComponent, definePage, defineStore };