From 8af9a0aa32435c99d56e2a046d701cc3e1bde67a Mon Sep 17 00:00:00 2001 From: zhangfisher Date: Tue, 27 Aug 2024 11:56:14 +0800 Subject: [PATCH] update --- example/src/forms/network/form.tsx | 237 ++++++++++----------- packages/core/src/action.tsx | 114 +++++++--- packages/core/src/errors.ts | 2 +- packages/core/src/field.tsx | 24 +-- packages/core/src/form.tsx | 65 +++--- packages/core/src/submit.tsx | 2 +- packages/core/src/types.ts | 9 +- packages/reactive/src/computed/computed.ts | 6 +- packages/reactive/src/computed/sync.ts | 2 +- packages/reactive/src/computed/types.ts | 25 ++- packages/reactive/src/store/useState.ts | 1 - 11 files changed, 248 insertions(+), 239 deletions(-) diff --git a/example/src/forms/network/form.tsx b/example/src/forms/network/form.tsx index 3c43b81..44eba53 100644 --- a/example/src/forms/network/form.tsx +++ b/example/src/forms/network/form.tsx @@ -35,7 +35,7 @@ const Network = createForm({ ip: { value: "1.1.1.1", title: "IP地址", - validate: computed(async (value: any) => { + validate: computed(async (value) => { await delay(2000); return validator.isIP(String(value)); },[],{async:true}), @@ -57,7 +57,7 @@ const Network = createForm({ title: "起始地址", value: "192.168.1.1", enable: computed((dhcp: any) => { - return dhcp.enable.value; + return dhcp.enable.value; },{ scope: ComputedScopeRef.Parent }), @@ -100,148 +100,129 @@ const Network = createForm({ help: "密码长度应不小于6位", validate: (value: string) => value.length >= 6, }, - submit: { // 这是一个动作, + submit: action(async (wifi:any)=>{ + await delay(2000) + console.log("提交wifi=",wifi) + },{ title: "提交wifi", - enable: (net: any) => net.interface.value === "wifi", - // validate: (value: string) => value.length > 6, - execute:async (wifi:any)=>{ - await delay(2000) - console.log("提交wifi=",wifi) - } - }, - timeoutSubmit: { // 这是一个动作, + enable: (net: any) => net.interface.value === "wifi" + }), + timeoutSubmit: action(async (wifi:any)=>{ + await delay(6000) + console.log("提交wifi=",wifi) + },{ title: "提交超时", - execute:computed(async (wifi:any)=>{ - await delay(6000) - console.log("提交wifi=",wifi) - },[],{ - timeout:[5 * 1000,5] - }) - }, - progressSubmit: { // 这是一个动作, - title: "提交进度", - execute:computed(async (fields:any,{getProgressbar,getSnap})=>{ - const bar = getProgressbar() - console.log("submit fields=",getSnap(fields)) - return new Promise((resolve)=>{ - let count = 0 , tmId = 0 - tmId = setInterval(()=>{ - if(count==100){ - clearInterval(tmId) - resolve() - } - bar.value(count++) - },200) - }) - },[]) - }, - retrySubmit: { // 这是一个动作, + timeout:[5 * 1000,5] + }), + progressSubmit: action(async (fields:any,{getProgressbar,getSnap})=>{ + const bar = getProgressbar() + console.log("submit fields=",getSnap(fields)) + return new Promise((resolve)=>{ + let count = 0 , tmId = 0 + tmId = setInterval(()=>{ + if(count==100){ + clearInterval(tmId) + resolve() + } + bar.value(count++) + },200) + }) + },{title: "提交进度"}), + retrySubmit: action(async ()=>{ + throw new Error("ERROR"+count++) + },{ title: "提交出错重试", - execute:computed(async ()=>{ - throw new Error("ERROR"+count++) - },[],{ - retry:[5,1000] // 重试5次,每次间隔1秒 - }) - }, - progressSubmit2: { // 这是一个动作, - title: "提交进度2", - execute:action(async (fields,{getProgressbar})=>{ - console.log("submit fields=",fields) - const bar = getProgressbar() - return new Promise((resolve)=>{ - let count = 0 , tmId = 0 - tmId = setInterval(()=>{ - if(count==100){ - clearInterval(tmId) - resolve() - } - bar.value(count++) - },200) - }) - }) - }, - standardSubmit: { // 这是一个动作, - title: "标准提交", - execute:action(async (fields)=>{ - console.log("formData=",fields) - }) - }, - cancelableSubmit: { // 这是一个动作, - title: "可取消的提交", - execute:action(async (fields,{abortSignal})=>{ - console.log("formData=",fields) - return new Promise((resolve,reject)=>{ - setTimeout(()=>{ + retry:[5,1000] // 重试5次,每次间隔1秒 + }), + progressSubmit2: action(async (fields,{getProgressbar})=>{ + console.log("submit fields=",fields) + const bar = getProgressbar() + return new Promise((resolve)=>{ + let count = 0 , tmId = 0 + tmId = setInterval(()=>{ + if(count==100){ + clearInterval(tmId) resolve() - },10* 1000) - abortSignal.addEventListener("abort",()=>{ - console.log("已取消:cancelled") - reject("cancelled") - }) - }) - },{ - scope:["dhcp"] - }) - } + } + bar.value(count++) + },200) + }) + },{ + title: "提交进度2" + }), + standardSubmit: action(async (fields)=>{ + console.log("formData=",fields) + },{ + title: "标准提交" + }), + cancelableSubmit:action(async (fields,{abortSignal})=>{ + console.log("formData=",fields) + return new Promise((resolve,reject)=>{ + setTimeout(()=>{ + resolve() + },10* 1000) + abortSignal.addEventListener("abort",()=>{ + console.log("已取消:cancelled") + reject("cancelled") + }) + }) + },{ + title: "可取消的提交", + scope:["dhcp"], + }) } }, actions: { - submit: { + submit: action(async (_:any,{abortSignal}) => { + return new Promise((resolve,reject)=>{ + setTimeout(()=>{ + resolve(count++) + },2000) + abortSignal.addEventListener("abort",()=>{ + reject("cancelled") + }) + }) + },{ title: "提交", enable: (root: any) => { return root.fields.wifi.ssid.value.length > 3 - }, - execute: action(async (_:any,{abortSignal}) => { - return new Promise((resolve,reject)=>{ - setTimeout(()=>{ - resolve(count++) - },2000) - abortSignal.addEventListener("abort",()=>{ - reject("cancelled") - }) - }) - }), - }, - errorSubmit: { - title: "提交错误", - execute: async () => { - await delay(1000); - throw new Error("提交错误"+count++); - }, - }, - timeoutSubmit: { - title: "提交超时倒计时", - execute: computed(async (scope: Dict) => { - console.log("ping=",Object.assign({},scope)); - await delay(5000); - },[],{timeout:2000}), - }, - ping: { + } + }), + errorSubmit: action(async () => { + await delay(1000); + throw new Error("提交错误"+count++); + },{ + title: "提交错误" + }), + timeoutSubmit: action(async (scope: Dict) => { + console.log("ping=",Object.assign({},scope)); + await delay(5000); + },{title: "提交超时倒计时",timeout:2000}), + ping: action(async (a: Dict) => { + await delay(1000); + console.log("ping=",Object.assign({},a)); + },{ title: "测试网络连通性", enable: computed((wifi: any) => { return wifi.ssid.value.length > 0 - },{scope:"fields.wifi"}), - execute: async (a: Dict) => { - await delay(1000); - console.log("ping=",Object.assign({},a)); - }, - }, + },{ + scope:"fields.wifi" + }) + }), // 向导表单:上一步 - previous:{ - enable: (wifi: any) => wifi.ssid.value.length > 0, - execute:async ()=>{ - return 1 - } - }, + previous:action(async (scope)=>{ + return scope + },{ + enable: (wifi: any) => wifi.ssid.value.length > 0 + }), // 向导表单:下一步 - next:{ - enable: (wifi: any) => wifi.ssid.value.length > 0, + next:action(async () => { + await delay(1000) + return 2 + },{ + enable: (wifi: any) => wifi.ssid.value.length > 0, visible:(scope:any)=>scope.orders.length<10, - execute: async () => { - await delay(1000) - return 2 - } - } + }) }, },{debug:true}); diff --git a/packages/core/src/action.tsx b/packages/core/src/action.tsx index 5c64045..77eaee1 100644 --- a/packages/core/src/action.tsx +++ b/packages/core/src/action.tsx @@ -34,17 +34,14 @@ import { ReactNode, useCallback, useRef, RefObject,useState} from "react"; import React from "react"; import type { FormDefine, FormStore } from "./form"; -import { AsyncComputedDefine, AsyncComputedGetter, AsyncComputedObject, ComputedDescriptorDefine, ComputedOptions, ComputedParams, Dict, RuntimeComputedOptions, computed, getVal, getValueByPath} from '@speedform/reactive'; +import { AsyncComputedDefine, AsyncComputedGetter, AsyncComputedObject, ComputedDescriptorDefine, ComputedOptions, ComputedParams, Dict, RuntimeComputedOptions, computed, getValueByPath} from '@speedform/reactive'; import { omit } from "flex-tools/object/omit"; -import { getFormData } from "./serialize"; +import { getFormData } from './serialize'; import { getId } from "./utils"; import { FIELDS_STATE_KEY } from "./consts"; +import { ComputableAttr } from "./types"; -export type ActionComputedAttr = ((fields:Fields)=>R) - | ((fields:Fields)=>Promise) - | ComputedDescriptorDefine - | R - + export type DefaultActionRenderProps={ title : string @@ -71,13 +68,13 @@ export type FormActionExecutor = (scope:Sco */ export interface FormActionDefine{ scope? : string | string[] // 动作提交范围 - title? : ActionComputedAttr // 动作标题 - help? : ActionComputedAttr // 动作帮助 - tips? : ActionComputedAttr // 动作提示 - visible?: ActionComputedAttr // 是否可见 - enable? : ActionComputedAttr // 是否可用 - count? : number // 动作执行次数 - execute : AsyncComputedDefine // 执行动作,用来对表单数据进行处理 + title? : ComputableAttr // 动作标题 + help? : ComputableAttr // 动作帮助 + tips? : ComputableAttr // 动作提示 + visible?: ComputableAttr // 是否可见 + enable? : ComputableAttr // 是否可用 + count? : number // 动作执行次数,每次执行时递增 + execute : AsyncComputedDefine // 执行动作,用来对表单数据进行处理 } export type FormAction = { @@ -300,21 +297,33 @@ export function createActionComponent(store:FormStore } + + +export type ActionComputedGetter = AsyncComputedGetter & { getFormData: (scope:Dict)=>Dict } + + /** - * 使用action来声明一个动作 * * 该函数实现以下功能: - * - 从store中获取动作的状态数据传递给Action的getter函数 * + * - 从store中获取动作的状态数据传递给Action的getter函数 + * - 从scope中获取表单数据 + * + * { + * + * execute:action(async (scope,{getFormData})=>{ + * data = getFormData(scope) + * + * }) + * } * * * @param getter * @param options */ -export function action(getter: AsyncComputedGetter,options?: ComputedOptions){ - +export function action2(getter: AsyncComputedGetter,options?: ComputedOptions){ return computed(async (scope:any,opts)=>{ const data = getFormData(Object.assign({},scope)) - return await (getter as unknown as AsyncComputedGetter)(data,opts) + return await (getter as unknown as ActionComputedGetter)(data,opts) },[],Object.assign({},options,{ scope : options?.scope, async : true, @@ -322,12 +331,53 @@ export function action(getter: AsyncComputedGett })) } +export type FormActionOptions = + Omit,'execute'> & Omit - - - - -export type UseActionType = (executor:AsyncComputedGetter,options?:ComputedOptions & {name?:string})=>FormActionState['execute'] +/** + * 用来声明一个动作 + * + * 该函数实现以下功能: + * + * { + * + * actions:{ + * submit:action(async (scope:T,{getFormData})=>{ + * const data = getFormData(scope) + * }), + * ping:action(()=>{},{ + * title : "", + * help : "", + * tips : "", + * visible: true, + * enable : true + * scope : "fields" + * }) + * } + * + * } + * + * + * + * @param getter + * @param options + * @returns + */ +export function action(getter: AsyncComputedGetter,options?: FormActionOptions){ + const opts = Object.assign({},options) + return { + execute: computed(async (scope:any,opts)=>{ + const data = getFormData(Object.assign({},scope)) + return await (getter as unknown as AsyncComputedGetter)(data,opts) + },[],Object.assign({},opts,{ + enable : true, + scope : opts.scope, + async : true, + immediate: false + })), + ...omit(opts,["title","help","tips","visible","enable"]) + } +} /** @@ -346,23 +396,21 @@ export type UseActionType = (executor:AsyncComput */ export function createUseAction(store:FormStore) { // useAction本质上就是创建一个计算属性 - return function useAction(executor:AsyncComputedGetter,options?:ComputedOptions & {name?:string}){ + return function useAction(executor:AsyncComputedGetter,options?:FormActionOptions){ const ref = useRef() const [state,setState] = store.useState() - const [actionName] = useState(()=>options?.name ? options?.name : getId()) + const [actionId] = useState(()=>options?.id ? options?.id : getId()) if(!ref.current){ - if(!(actionName in state.actions)){ + if(!(actionId in state.actions)){ setState((draft:any)=>{ - draft.actions[actionName] = { - execute:action(executor,options) - } + draft.actions[actionId] = action(executor,options) }) // 读取一次以触发计算属性对象的创建 - getValueByPath(state,['actions',actionName]) + getValueByPath(state,['actions',actionId]) } - ref.current = actionName + ref.current = actionId } - return getValueByPath(state,['actions',actionName]).execute as FormActionState['execute'] + return getValueByPath(state,['actions',actionId]).execute as FormActionState['execute'] } } diff --git a/packages/core/src/errors.ts b/packages/core/src/errors.ts index 4d8fd8b..795ddea 100644 --- a/packages/core/src/errors.ts +++ b/packages/core/src/errors.ts @@ -1,5 +1,5 @@ export class ValidationError extends Error { - constructor(message: string) { + constructor(message?: string) { super(message); this.name = "ValidationError"; } diff --git a/packages/core/src/field.tsx b/packages/core/src/field.tsx index a5f64ca..778ec84 100644 --- a/packages/core/src/field.tsx +++ b/packages/core/src/field.tsx @@ -1,7 +1,7 @@ import React from 'react' import { ChangeEventHandler, ReactNode, useCallback,useRef,useState } from "react"; import { debounce as debounceWrapper } from './utils'; -import { ComputedAttr } from "./types"; +import { ComputableAttr } from "./types"; import type { FormStore, RequiredFormOptions } from "./form"; import { FIELDS_STATE_KEY } from "./consts"; import { Dict,getVal, setVal } from "@speedform/reactive"; @@ -191,17 +191,17 @@ export interface IFieldProps{ export interface FormField{ value : T; - title? : ComputedAttr; // 标题 - initial? : ComputedAttr; // 默认值 - oldValue? : ComputedAttr; // 默认值 - help? : ComputedAttr; // 提示信息 - placeholder? : ComputedAttr; // 占位符 - required? : ComputedAttr; // 是否必填 - readonly? : ComputedAttr; // 是否只读 - visible? : ComputedAttr; // 是否可见 - enable? : ComputedAttr; // 是否可用 - validate? : ComputedAttr; // 验证 - select? : ComputedAttr // 枚举值 + title? : ComputableAttr; // 标题 + initial? : ComputableAttr; // 默认值 + oldValue? : ComputableAttr; // 默认值 + help? : ComputableAttr; // 提示信息 + placeholder? : ComputableAttr; // 占位符 + required? : ComputableAttr; // 是否必填 + readonly? : ComputableAttr; // 是否只读 + visible? : ComputableAttr; // 是否可见 + enable? : ComputableAttr; // 是否可用 + validate? : ComputableAttr; // 验证 + select? : ComputableAttr // 枚举值 } export type FormFieldBase = { diff --git a/packages/core/src/form.tsx b/packages/core/src/form.tsx index fb1cc67..744b0d4 100644 --- a/packages/core/src/form.tsx +++ b/packages/core/src/form.tsx @@ -41,19 +41,20 @@ import React, { ReactNode, useId, useRef, useState } from 'react' import { useCallback } from "react"; import type { Dict,RequiredComputedState, ComputedOptions, IStore, StoreOptions, ComputedState } from "@speedform/reactive"; import { createStore, OBJECT_PATH_DELIMITER, pathStartsWith } from "@speedform/reactive"; -import type { ReactFC, ComputedAttr } from "./types"; +import type { ReactFC, ComputableAttr } from "./types"; import { createFieldComponent, FormFields } from './field'; import { createFieldGroupComponent } from "./fieldGroup"; import { assignObject } from "flex-tools/object/assignObject"; -import { ActionRenderProps, FormActions, UseActionType, createActionComponent, createUseAction, getAction } from './action'; +import { ActionRenderProps, FormActions, createActionComponent, createUseAction, getAction } from './action'; import { FIELDS_STATE_KEY, VALIDATE_COMPUTED_GROUP } from './consts'; import { defaultObject } from "flex-tools/object/defaultObject"; -import { createObjectProxy, getId } from "./utils"; +import { createObjectProxy } from "./utils"; import { createLoadApi, createGetValuesApi } from "./serialize"; import { createValidator, isValidateField, validate } from "./validate"; import { createSubmitComponent } from './submit'; import { $reset, createResetComponent } from "./reset"; import { dirty } from "./dirty"; +import { ValidationError } from './errors'; export const defaultFormProps = { name : "SpeedForm", @@ -86,16 +87,16 @@ export type FormStore = IStore> = ReactFC>; export type FormSchemaBase = { - name : ComputedAttr - title : ComputedAttr - help : ComputedAttr - tips : ComputedAttr - visible : ComputedAttr - url : ComputedAttr - enable : ComputedAttr - validate: ComputedAttr - readonly: ComputedAttr - dirty : ComputedAttr + name : ComputableAttr + title : ComputableAttr + help : ComputableAttr + tips : ComputableAttr + visible : ComputableAttr + url : ComputableAttr + enable : ComputableAttr + validate: ComputableAttr + readonly: ComputableAttr + dirty : ComputableAttr } export type FormDefine = Partial & { @@ -282,27 +283,7 @@ export function getFieldName(valuePath:string[]){ valuePath.slice(0,-1).join(".") : valuePath.join(".") : '' } -export type FormObject = { - state: FormState, - useState: (fn: (state: FormState) => any) => any, - setState: (fn: (draft: FormState) => void) => void, - Form: FormComponent, - Field: ReactFC, - Group: ReactFC, - Action: ReactFC, - Submit: ReactFC, - Reset: ReactFC, - useAction: UseActionType, - fields: State['fields'], - actions: State['actions'], - getAction: (name: string) => any, - freeze: (value?: boolean) => void, - load: (data: Dict) => void, - getValues: () => Dict, - computedObjects: Dict, - watchObjects: Dict, - validate: (value?: Dict) => Promise -} + /** * 创建声明表单 * @@ -357,6 +338,7 @@ export function createForm(schema: State,op type StoreType = FormStore type FieldsType = StateType['fields'] type ActionsType = StateType['actions'] + type UseActionType = ReturnType // 将store强制转换为FormStore,因为表单的根元数据如dirty等属性需要提供默认类型提示 const formStore = store as unknown as StoreType @@ -394,6 +376,7 @@ export type FormProps = Re action? : string; // 表单提交地址 scope? : string | string[] // 提交范围, 默认是整个表单fields,也可以指定某个字段或字段组 valid? : boolean // 是否进行校验 + mode? : 'ajax' | 'standard' // 提交模式 indicator?: FormIndicatorRender // 提交指示器 onSubmit? : (value: RequiredComputedState) => void; onReset? : (value: RequiredComputedState) => void; @@ -447,25 +430,29 @@ function createFormComponent(store: FormStore,f // 动态创建一个Action const actionId = useId() - const actionArgs = useAction(async (data:any,params)=>{ + const actionArgs = useAction(async (data:Dict,params)=>{ // 运行表单校验 if(formOptions.validAt==='submit' || props.valid!==false){ if(scope && scope.length>0){ // 指定了提交范围 const scopeValue = typeof(scope)=='string' ? scope.split(OBJECT_PATH_DELIMITER) : scope await store.computedObjects.run((cobj)=>{ + if(cobj.path.length>1 && cobj.path[0]==FIELDS_STATE_KEY && cobj.path[cobj.path.length-1]==='validate'){ + + } return pathStartsWith(scopeValue,cobj.path) },undefined,{wait:true}) + }else{ // 全局提交 await store.computedObjects.runGroup(VALIDATE_COMPUTED_GROUP,undefined,{wait:true}) + if(!store.state.validate){ + throw new ValidationError() + } } // 检查校验结果 - - - } - },{name: actionId,scope}) + },{id: actionId,scope}) // 提交表单 const onSubmitCallback = useCallback(async (ev: React.FormEvent) => { diff --git a/packages/core/src/submit.tsx b/packages/core/src/submit.tsx index 604e7cb..e37bb47 100644 --- a/packages/core/src/submit.tsx +++ b/packages/core/src/submit.tsx @@ -207,7 +207,7 @@ export function createSubmitComponent(store: FormStor } -export type SubmitAsyncComputedGetter = AsyncComputedGetter +export type SubmitAsyncComputedGetter = AsyncComputedGetter export type SubmitActionOptions = ComputedOptions diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 604ceb1..5e45aa5 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -2,17 +2,12 @@ import { AsyncComputedObject,ComputedDescriptor } from "@speedform/reactive"; // 用来声明表单定义中的动态计算属性 -export type ComputedAttr = ((...args:Args)=>R) +export type ComputableAttr = ((...args:Args)=>R) | ((...args:Args)=>Promise) - | AsyncComputedObject + // | AsyncComputedObject | ComputedDescriptor | R -export type ComputedAttr1 = ((scope:Scope)=>R) - | ((scope:Scope)=>Promise) - | AsyncComputedObject - | ComputedDescriptor - | R export type ReactFC = React.FC,'className' | 'style'> & Props>> diff --git a/packages/reactive/src/computed/computed.ts b/packages/reactive/src/computed/computed.ts index 694417a..f7c67ef 100644 --- a/packages/reactive/src/computed/computed.ts +++ b/packages/reactive/src/computed/computed.ts @@ -19,9 +19,9 @@ import { normalizeDeps } from "../utils/normalizeDeps"; * @returns * */ -export function computed( getter: AsyncComputedGetter,depends:ComputedDepends,options?: ComputedOptions): ComputedDescriptor; -export function computed( getter: ComputedGetter, options?: ComputedOptions): R -export function computed( getter: any,depends?:any, options?: ComputedOptions):any { +export function computed( getter: AsyncComputedGetter,depends:ComputedDepends,options?: ComputedOptions): ComputedDescriptor; +export function computed( getter: ComputedGetter, options?: ComputedOptions): R +export function computed( getter: any,depends?:any, options?: ComputedOptions):any { if (typeof getter != "function") throw new Error("computed getter must be a function"); diff --git a/packages/reactive/src/computed/sync.ts b/packages/reactive/src/computed/sync.ts index 19cdca4..9f2f346 100644 --- a/packages/reactive/src/computed/sync.ts +++ b/packages/reactive/src/computed/sync.ts @@ -108,6 +108,6 @@ export function createComputedMutate(computedParams:I // 5. 创建计算对象实例 const computedObject = new ComputedObject(store,selfReactiveable,valuePath,computedOptions) - if(computedOptions.save) store.computedObjects.set(computedId,computedObject) + if(computedOptions.objectify) store.computedObjects.set(computedId,computedObject) return computedObject } \ No newline at end of file diff --git a/packages/reactive/src/computed/types.ts b/packages/reactive/src/computed/types.ts index 98b56a8..f5e1c09 100644 --- a/packages/reactive/src/computed/types.ts +++ b/packages/reactive/src/computed/types.ts @@ -5,18 +5,17 @@ import type { ComputedScope, IStore } from "../store/types"; import { Dict } from "../types" import { WatchDescriptor } from "../watch"; -import { Reactiveable } from "../reactives/types"; -import { ComputedObject } from "./computedObject"; +import { Reactiveable } from "../reactives/types"; // 指向helux的IOperateParams类型,但是我们只用到其是的部分类型 // Pick; export type IComputeParams = { - keyPath:string[] // 路径 - fullKeyPath:string[] // 完整路径,包括自身 - value:any - parent?:any - replaceValue:(newValue: any) => void; + keyPath : string[] // 路径 + fullKeyPath : string[] // 完整路径,包括自身 + value : any + parent? : any + replaceValue: (newValue: any) => void; } @@ -207,7 +206,7 @@ export interface ComputedProgressbar{ export type ComputedDepends =Array> export type ComputedGetter = (scopeDraft: Scope) => Exclude> - export type AsyncComputedGetter = (scopeDraft:Scope,options:Required) => Promise + export type AsyncComputedGetter = (scopeDraft:Scope,options:Required & P) => Promise // 当调用run方法时,用来传参覆盖原始的计算参数 export type RuntimeComputedOptions = Pick @@ -220,7 +219,7 @@ export interface ComputedProgressbar{ retry : number // 重试次数,当执行重试操作时,会进行倒计时,每次重试-1,直到为0时停止重试 result : Result; // 计算结果保存到此处 run : (options?:RuntimeComputedOptions) => {}; // 重新执行任务 - cancel : ()=>void // 中止正在执行的异步计算 + cancel : ()=>void // 中止正在执行的异步计算 } & ExtAttrs @@ -244,16 +243,16 @@ export interface StateValueDescriptorParams = AsyncComputedGetter | ComputedDescriptor +export type AsyncComputedDefine = AsyncComputedGetter | ComputedDescriptor -export type ComputedDescriptorDefine = { - getter: AsyncComputedGetter | ComputedGetter; +export type ComputedDescriptorDefine = { + getter: AsyncComputedGetter | ComputedGetter; options: ComputedOptions; } -export interface ComputedDescriptor { +export interface ComputedDescriptor { ():ComputedDescriptorDefine __COMPUTED__: 'sync' | 'async' | 'watch' } diff --git a/packages/reactive/src/store/useState.ts b/packages/reactive/src/store/useState.ts index 44d7ff0..5572256 100644 --- a/packages/reactive/src/store/useState.ts +++ b/packages/reactive/src/store/useState.ts @@ -1,4 +1,3 @@ -import { RequiredComputedState } from "../computed/types" import { StateGetter, StateSetter } from "./types" import { IStore, Dict } from "../types"