import type { ComputedRef, Ref } from 'vue'; import type { FormProps, FormSchema, FormActionType } from '../types/form'; import { unref, toRaw } from 'vue'; import { isDef, isFunction } from '@/utils/is'; declare type EmitType = (event: string, ...args: any[]) => void; interface UseFormActionContext { emit: EmitType; getProps: ComputedRef; getSchema: ComputedRef; formModel: Recordable; formElRef: Ref; defaultFormModel: Recordable; loadingSub: Ref; handleFormValues: Function; } export function useFormEvents({ emit, getProps, formModel, getSchema, formElRef, defaultFormModel, loadingSub, handleFormValues, }: UseFormActionContext) { // 验证 async function validate() { return unref(formElRef)?.validate(); } // 提交 async function handleSubmit(e?: Event): Promise { e && e.preventDefault(); loadingSub.value = true; const { submitFunc } = unref(getProps); if (submitFunc && isFunction(submitFunc)) { await submitFunc(); loadingSub.value = false; return false; } const formEl = unref(formElRef); if (!formEl) return false; try { await validate(); const values = getFieldsValue(); loadingSub.value = false; emit('submit', values); return values; } catch (error: any) { emit('submit', false); loadingSub.value = false; console.error(error); return false; } } //清空校验 async function clearValidate(name?) { await unref(formElRef as any)?.clearValidate(name); } //重置表单 async function resetFieldsForm() { await unref(formElRef as any)?.resetFields(); } //重置 async function resetFields(): Promise { const { resetFunc, submitOnReset } = unref(getProps); resetFunc && isFunction(resetFunc) && (await resetFunc()); const formEl = unref(formElRef); if (!formEl) return; Object.keys(formModel).forEach((key) => { formModel[key] = unref(defaultFormModel)[key] || null; }); await resetFieldsForm(); const fromValues = handleFormValues(toRaw(unref(formModel))); emit('reset', fromValues); submitOnReset && (await handleSubmit()); } //获取表单值 function getFieldsValue(): Recordable { const formEl = unref(formElRef); if (!formEl) return {}; return handleFormValues(toRaw(unref(formModel))); } //设置表单字段值 function setFieldsValue(values: Recordable): void { const fields = unref(getSchema) .map((item) => item.name) .filter(Boolean); // 兼容 a.b.c 写法 const decimal = '.'; const decimalKeyList = fields.filter((item) => item.indexOf(decimal) >= 0); Object.keys(values).forEach((key) => { const value = values[key]; const isKey = Reflect.has(values, key); if (isKey && fields.includes(key)) { formModel[key] = value; } else { decimalKeyList.forEach((itemKey: string) => { try { const value = eval('values' + decimal + itemKey); if (isDef(value)) { formModel[itemKey] = value; } } catch (e) { console.error(e); } }); } }); } function setLoadingSub(value: boolean): void { loadingSub.value = value; } return { handleSubmit, validate, resetFields, getFieldsValue, clearValidate, setFieldsValue, setLoadingSub, }; }