| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- <template>
- <Form
- ref="formRef"
- v-bind="formProps"
- :model="formModel"
- :rules="formRules"
- >
- <DynamicFormCate
- v-if="formModel"
- :formModel="formModel"
- :formDefine="formDefine"
- :formDefineParentKey="''"
- :formDefineParentLabel="''"
- />
- </Form>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, provide, reactive, ref, toRef, watch, type PropType } from 'vue';
- import { waitTimeOut } from '@imengyu/imengyu-utils';
- import DynamicFormCate from './DynamicFormCate.vue';
- import Form, { type FormProps } from '../form/Form.vue';
- import type { FormDefine, FormDefineItem, FormExport } from '.';
- import type { Rules } from 'async-validator';
- const props = defineProps({
- formDefine: {
- type: Object as PropType<FormDefine>,
- default: () => ({})
- },
- formProps: {
- type: Object as PropType<Omit<FormProps, 'model' | 'rules'>>,
- default: () => ({})
- },
- formGlobalParams: {
- type: Object,
- default: () => ({})
- },
- });
- const formRef = ref<any>();
- const formModel = ref<any>(null);
- const formRules = computed(() => {
- const rules: Rules = {};
- function loop(prevKey: string, arr: FormDefineItem[]) {
- if (!arr || !(arr instanceof Array))
- return;
- for (const item of arr) {
- const key = prevKey ? `${prevKey}.${item.name}` : item.name;
- if (key && item.rules)
- rules[key] = item.rules;
- if (item.children) {
- loop(
- item.children.propNestType === 'flat' ? key : prevKey,
- item.children.items
- );
- }
- }
- }
- loop('', props.formDefine.items);
- return rules;
- });
- const formGlobalParams = toRef(props.formGlobalParams);
- provide('formTopModel', formModel);
- provide('formGlobalParams', formGlobalParams);
- watch(() => props.formDefine, (v) => {
- reloadFormData();
- });
- let isErrorState = false;
- let initCb : () => any = () => {
- return {};
- };
- function initFormData(data: () => any) {
- initCb = data;
- }
- function loadFormData(value?: Record<string, any>) {
- const obj = reactive(initCb());
- function loop(prevKey: string, arr: FormDefineItem[]) {
- if (!arr || !(arr instanceof Array))
- return;
- for (let index = 0; index < arr.length; index++) {
- const item = arr[index];
- const key = prevKey ? `${prevKey}.${item.name}` : item.name;
- if (key) {
- const valueProvided = value?.[key] ;
- obj[key] = valueProvided == null || valueProvided == undefined ?
- (typeof item.defaultValue === 'function' ? item.defaultValue() : item.defaultValue)
- : valueProvided ?? null;
- item.fullName = key;
- } else {
- item.fullName = '';
- }
- if (item.children)
- loop(
- item.children.propNestType === 'flat' ? key : prevKey,
- item.children.items
- );
- }
- }
- loop('', props.formDefine.items);
- formModel.value = obj;
- }
- async function submitForm<T = Record<string, any>>() : Promise<T|null> {
- await formRef.value.clearValidate();
- await waitTimeOut(50);
-
- try {
- await formRef.value.validate();
- } catch (e) {
- if (isErrorState)
- uni.showToast({
- title: '表单中有未填写项,请检查',
- icon: 'none'
- });
- console.log(e);
- isErrorState = true;
- return null;
- }
- isErrorState = false;
- return formModel.value;
- }
- function resetForm() {
- loadFormData();
- }
- function reloadFormData() {
- if (!formModel.value)
- loadFormData();
- }
- onMounted(() => {
- setTimeout(() => reloadFormData(), 300);
- });
- defineExpose<FormExport>({
- getFormRef: () => formRef.value,
- getFormData: () => formModel.value,
- initFormData,
- loadFormData,
- submitForm,
- resetForm,
- })
- </script>
|