import { ref, onUnmounted, unref, nextTick, watchEffect } from 'vue';
|
|
import { isInSetup } from '/@/utils/helper/vueHelper';
|
import { isProdMode } from '/@/utils/env';
|
import { error } from '/@/utils/log';
|
import { getDynamicProps } from '/@/utils';
|
|
import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
|
import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
import type { DynamicProps } from '/@/types/utils';
|
|
export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>;
|
|
type Props = Partial<DynamicProps<FormProps>>;
|
|
export function useForm(props?: Props): UseFormReturnType {
|
isInSetup();
|
|
const formRef = ref<Nullable<FormActionType>>(null);
|
const loadedRef = ref<Nullable<boolean>>(false);
|
|
async function getForm() {
|
const form = unref(formRef);
|
if (!form) {
|
error(
|
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!'
|
);
|
}
|
await nextTick();
|
return form as FormActionType;
|
}
|
|
function register(instance: FormActionType) {
|
isProdMode() &&
|
onUnmounted(() => {
|
formRef.value = null;
|
loadedRef.value = null;
|
});
|
if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return;
|
|
formRef.value = instance;
|
|
loadedRef.value = true;
|
|
watchEffect(() => {
|
props && instance.setProps(getDynamicProps(props));
|
});
|
}
|
|
const methods: FormActionType = {
|
scrollToField: async (name: NamePath, options?: ScrollOptions | undefined) => {
|
const form = await getForm();
|
form.scrollToField(name, options);
|
},
|
setProps: async (formProps: Partial<FormProps>) => {
|
const form = await getForm();
|
form.setProps(formProps);
|
},
|
|
updateSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => {
|
const form = await getForm();
|
form.updateSchema(data);
|
},
|
|
clearValidate: async (name?: string | string[]) => {
|
const form = await getForm();
|
form.clearValidate(name);
|
},
|
|
resetFields: async () => {
|
getForm().then(async (form) => {
|
await form.resetFields();
|
});
|
},
|
|
removeSchemaByFiled: async (field: string | string[]) => {
|
const form = await getForm();
|
form.removeSchemaByFiled(field);
|
},
|
|
// TODO promisify
|
getFieldsValue: <T>() => {
|
return unref(formRef)?.getFieldsValue() as T;
|
},
|
|
setFieldsValue: async <T>(values: T) => {
|
const form = await getForm();
|
form.setFieldsValue<T>(values);
|
},
|
|
appendSchemaByField: async (schema: FormSchema, prefixField?: string | undefined) => {
|
const form = await getForm();
|
form.appendSchemaByField(schema, prefixField);
|
},
|
|
submit: async (): Promise<any> => {
|
const form = await getForm();
|
return form.submit();
|
},
|
|
validate: async (nameList?: NamePath[]): Promise<Recordable> => {
|
const form = await getForm();
|
return form.validate(nameList);
|
},
|
|
validateFields: async (nameList?: NamePath[]): Promise<Recordable> => {
|
const form = await getForm();
|
return form.validateFields(nameList);
|
},
|
};
|
|
return [register, methods];
|
}
|