import { Form as BaseForm, FormInstance as BaseFormInstance, Message } from "@arco-design/web-vue"; import { assign, cloneDeep, defaultsDeep } from "lodash-es"; import { PropType } from "vue"; import { FormItem, IFormItem } from "./form-item"; import { NodeType, nodeMap } from "./form-node"; import { config } from "./form-config"; type SubmitFn = (arg: { model: Record; items: IFormItem[] }) => Promise; /** * 表单组件 */ export const Form = defineComponent({ name: "Form", props: { /** * 表单数据 */ model: { type: Object as PropType>, default: () => reactive({}), }, /** * 表单项 */ items: { type: Array as PropType, default: () => [], }, /** * 提交表单 */ submit: { type: Function as PropType, }, /** * 传给Form组件的参数 */ formProps: { type: Object as PropType>, }, }, setup(props) { const model = cloneDeep(props.model); const formRef = ref>(); const loading = ref(false); props.items.forEach((item: any) => { const node = nodeMap[item.type as NodeType]; defaultsDeep(item, { nodeProps: node?.nodeProps ?? {} }); (node as any)?.init?.({ item, model: props.model }); }); const getItem = (field: string) => { return props.items.find((item) => item.field === field); }; const getModel = () => { return config.getModel(props.model); }; const setModel = (data: Record) => { config.setModel(props.model, data); }; const resetModel = () => { assign(props.model, model); }; const submitForm = async () => { if (await formRef.value?.validate()) { return; } const model: Record = getModel(); try { loading.value = true; const res = await props.submit?.({ model, items: props.items }); res?.message && Message.success(`提示: ${res.message}`); } catch (error: any) { const message = error?.response?.data?.message || error?.message; message && Message.error(`提示: ${message}`); } finally { loading.value = false; } }; return { formRef, loading, getItem, submitForm, resetModel, setModel, getModel, }; }, render() { (this.items as any).instance = this; const props = { items: this.items, model: this.model, slots: this.$slots, }; return ( {this.items.map((item) => ( ))} ); }, }); export type FormInstance = InstanceType; export type FormProps = FormInstance["$props"]; export type FormDefinedProps = Pick;