DynamicForm.ts 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import type { Rule, RuleItem, Rules } from "async-validator";
  2. import type { FormInstance, FormProps } from "../form/Form.vue";
  3. import type { FieldProps } from "../form/Field.vue";
  4. import type { ColProps } from "../layout/grid/Col.vue";
  5. import type { RowProps } from "../layout/grid/Row.vue";
  6. export interface IDynamicFormOptions {
  7. /**
  8. * 表单额外属性
  9. */
  10. formAdditionaProps?: FormProps;
  11. /**
  12. * 表单校验规则
  13. */
  14. formRules?: Rules;
  15. /**
  16. * 子条目定义
  17. */
  18. formItems: IDynamicFormItem[];
  19. /**
  20. * 是否在根级别抑制错误提示
  21. */
  22. suppressRootError?: boolean;
  23. /**
  24. * 空文本
  25. */
  26. emptyText?: string;
  27. /**
  28. * 是否禁用表单
  29. */
  30. disabled?: boolean;
  31. /**
  32. * 是否屏蔽所有子条目空错误。默认否
  33. * @default false
  34. */
  35. suppressEmptyError?: boolean,
  36. /**
  37. * 当显示嵌套的表单对象条目时是否在前部显示缩进,
  38. * 缩进大小可使用 CSS 变量 `--dynamic-form-item-nest-margin` 自定义。默认是 20px
  39. * @default true
  40. */
  41. nestObjectMargin?: boolean,
  42. }
  43. /**
  44. * 表单动态属性定义
  45. */
  46. export declare type IDynamicFormItemCallback<T> = {
  47. /**
  48. * 预留,暂未使用
  49. */
  50. type?: string;
  51. /**
  52. * @param model 当前表单条目的值
  53. * @param rawModel 整个 form 的值 (最常用,当两个关联组件距离较远时,可以从顶层的 rawModel 里获取)
  54. * @param parentModel 父表单元素的值 (上一级的值,只在列表场景的使用,例如列表某个元素的父级就是整个 item)
  55. * @param item 当前表单条目信息
  56. */
  57. callback: (model: any, rawModel: any, parentModel: any, params: {
  58. /**
  59. * 当前表单条目
  60. */
  61. item: IDynamicFormItem,
  62. /**
  63. * 当前表单条目的父级,为空时表示当前条目为根级别。
  64. */
  65. parent?: IDynamicFormItem,
  66. /**
  67. * 当前表单组件实例
  68. */
  69. form: IDynamicFormRef,
  70. /**
  71. * 全局参数。由表单组件顶层添加额外的参数。
  72. */
  73. formGlobalParams: IDynamicFormObject,
  74. /**
  75. * 当前条目校验数据
  76. */
  77. formRules?: Record<string, Rule>,
  78. /**
  79. * 是否是所在层级的第一个表单项
  80. */
  81. isFirst: boolean,
  82. /**
  83. * 是否是所在层级的最后一个表单项
  84. */
  85. isLast: boolean,
  86. }) => T;
  87. };
  88. export type IDynamicFormItemCallbackAdditionalProps<T> = { [P in keyof T]?: T[P]|IDynamicFormItemCallback<T[P]> }
  89. export type DynamicFormNestNameGenerateType = 'dot'|'array'
  90. /**
  91. * 表单事件中心消息名称
  92. */
  93. /**
  94. * 重新加载表单项目。由条目自由处理。
  95. */
  96. export const MESSAGE_RELOAD = 'reload';
  97. export type IDynamicFormObject = Record<string, any>
  98. /**
  99. * 表单动态组件属性定义
  100. */
  101. export interface IDynamicFormComponentAdditionalDefine {
  102. /**
  103. * 组件名称
  104. */
  105. name: string,
  106. /**
  107. * 是否需要显示右侧箭头
  108. */
  109. needArrow?: boolean,
  110. /**
  111. * 传递给表单条目的参数
  112. */
  113. itemProps?: FieldProps,
  114. /**
  115. * 传递给组件的参数
  116. */
  117. props?: Record<string, unknown>|unknown,
  118. }
  119. export interface IDynamicFormItem {
  120. /**
  121. * 表单项显示标签
  122. */
  123. label?: string|IDynamicFormItemCallback<string>;
  124. /**
  125. * 属性名称
  126. */
  127. name: string;
  128. /**
  129. * 表单项组件类型
  130. */
  131. type?: string;
  132. /**
  133. * 传递给条目组件的参数。(允许动态回调)
  134. */
  135. additionalProps?: Record<string, unknown|IDynamicFormItemCallback<unknown>>|unknown;
  136. /**
  137. * 传递给FormItem组件的参数
  138. */
  139. formProps?: FieldProps;
  140. /**
  141. * 默认值,用于默认数据生成
  142. */
  143. defaultValue?: any;
  144. /**
  145. * 是否屏蔽空错误。默认否
  146. * @default false
  147. */
  148. suppressEmptyError?: boolean,
  149. /**
  150. * 当前条目的校验规则
  151. */
  152. rules?: RuleItem[],
  153. /**
  154. * 子条目,在对象中为对象子属性,在数组中为数组条目(单条目按单项控制,多条目按对象看待控制)
  155. */
  156. children?: IDynamicFormItem[],
  157. /**
  158. * 是否显示。当为undefined时,默认显示。
  159. */
  160. show?: boolean|IDynamicFormItemCallback<boolean>|undefined,
  161. /**
  162. * 是否禁用当前表单项
  163. */
  164. disabled?: boolean|IDynamicFormItemCallback<boolean>;
  165. /**
  166. * 当前条目组件加载时发生事件
  167. * @param nowModel 当前表单条目的值
  168. * @param rawModel 顶层数据对象
  169. * @param ref 组件实例
  170. * @returns
  171. */
  172. mounted?: (nowModel: any, rawModel: any, ref: any) => void;
  173. /**
  174. * 当前条目组件卸载时发生事件
  175. * @param nowModel 当前表单条目的值
  176. * @param rawModel 顶层数据对象
  177. * @param ref 组件实例
  178. * @returns
  179. */
  180. beforeUnmount?: (nowModel: any, rawModel: any, ref: any) => void;
  181. /**
  182. * 当前条目数据更改时发生事件
  183. * @param oldValue 旧值
  184. * @param newValue 新值
  185. * @param topModel 顶层数据对象
  186. * @param ref 组件实例
  187. * @returns
  188. */
  189. watch?: (oldValue: any, newValue: any, rawModel: any, ref: any) => void;
  190. /**
  191. * 监听从外部或者其他表单发送过来的消息事件
  192. * @param messageName 消息名称
  193. * @param data 消息数据
  194. * @param getComponentRef 当前组件的实例
  195. * @returns
  196. */
  197. message?: (messageName: string, data: unknown, getComponentRef: () => unknown) => void,
  198. /**
  199. * 当子对象为数组时,可设置这个自定义回调。用于添加按钮新建一个对象,如果这个函数为空,则没有添加按钮。
  200. */
  201. newChildrenObject?: (arrayNow: unknown[]) => unknown;
  202. /**
  203. * 当子对象为数组时,可设置这个自定义回调。删除按钮回调,可选,不提供时默认操作为将 item 从 array 中移除。
  204. */
  205. deleteChildrenCallback?: (arrayNow: unknown[], deleteObject: unknown) => unknown;
  206. /**
  207. * 子条目的 Col 配置属性(应用到当前条目的所有子条目上)。仅在 object 或者其他容器条目中有效。
  208. */
  209. childrenColProps?: ColProps,
  210. /**
  211. * 当前条目的 Col 配置属性(应用到当前条目上)。仅在 object 或者其他容器条目中有效。
  212. */
  213. colProps?: ColProps,
  214. /**
  215. * 当前条目的 Row 配置属性(应用到当前条目上)。仅在 object 或者其他容器条目中有效。
  216. */
  217. rowProps?: RowProps,
  218. /**
  219. * 当显示嵌套的表单对象条目时是否在前部显示缩进。默认是
  220. */
  221. nestObjectMargin?: boolean,
  222. //内部使用,不建议外部调用
  223. fullName?: string;
  224. }
  225. export interface IDynamicFormRef {
  226. /**
  227. * 获取表单组件的 Ref
  228. * @returns
  229. */
  230. getFormRef: () => FormInstance;
  231. /**
  232. * 获取指定表单项组件的 Ref
  233. * @returns
  234. */
  235. getFormItemControlRef: <T>(key: string) => T;
  236. /**
  237. * 触发提交。同 getFormRef().submit() 。
  238. * @returns
  239. */
  240. submit: () => void;
  241. /**
  242. * 验证当前表单数据是否有效。同 getFormRef().validate() 。
  243. * @returns
  244. */
  245. validate: () => Promise<void>;
  246. /**
  247. * 外部修改指定单个 field 的数据
  248. * @param path 路径
  249. * @param value 值
  250. * @returns
  251. */
  252. setValueByPath: (path: string|string[], value: unknown) => void,
  253. /**
  254. * 外部获取指定单个 field 的数据
  255. * @param path 路径
  256. * @returns
  257. */
  258. getValueByPath: (path: string|string[]) => unknown,
  259. /**
  260. * 向所有或者指定的子组件分发消息事件。
  261. * @param messageName 消息名称。
  262. * @param data 可选参数。
  263. * @param receiveFilter 可选名称筛选正则,此正则通过名称的子组件会接受事件,其他则不会。
  264. * @returns
  265. */
  266. dispatchMessage: (messageName: string, data?: unknown, receiveFilter?: RegExp) => void;
  267. /**
  268. * 向所有子组件分发重新加载消息事件。
  269. * @returns
  270. */
  271. dispatchReload: () => void;
  272. /**
  273. * 获取当前表单中可见的所有字段名
  274. */
  275. getVisibleFormNames: () => string[];
  276. /**
  277. * 初始化表单默认值到模型中,对于已有数据非空的字段,不会覆盖已有的值。
  278. * @returns
  279. */
  280. initDefaultValuesToModel: () => void;
  281. }
  282. /**
  283. * 默认的动态表单属性
  284. */
  285. export let defaultDynamicFormOptions = {} as IDynamicFormOptions;
  286. /**
  287. * 配置默认的动态表单属性,配置后将会对所有动态表单生效。
  288. * @param options 参数
  289. */
  290. export function configDefaultDynamicFormOptions(options: Omit<IDynamicFormOptions, 'formItems'>) {
  291. defaultDynamicFormOptions = {
  292. ...defaultDynamicFormOptions,
  293. ...options,
  294. };
  295. }
  296. export type IEvaluateCallback = <T>(val: T | IDynamicFormItemCallback<T>) => T;
  297. export type IDynamicFormMessageCenterCallback = (messageName: string, data: unknown) => void;
  298. export interface IDynamicFormMessageCenter {
  299. addInstance: (name: string, fn: IDynamicFormMessageCenterCallback) => void,
  300. removeInstance: (name: string) => void,
  301. }