| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- <template>
- <Col
- v-if="isShow"
- :class="[
- 'dynamic-form-item-wrapper',
- finalOptions?.nestObjectMargin !== false && item.nestObjectMargin !== false ? 'nest-with-margin' : '',
- ]"
- :data-dynamic-form-item="item.name"
- :data-dynamic-form-item-type="item.type"
- v-bind="{
- ...colProps,
- ...(item.colProps as {})
- }"
- >
- <!--对象组-->
- <DynamicFormCheckEmpty
- v-if="item.type === 'object'"
- :model="model"
- :modelWithDefault="finalModel"
- :suppressEmptyError="editmode || finalOptions?.suppressEmptyError || item.suppressEmptyError"
- :name="name"
- checkType="object"
- >
- <!--标题-->
- <DynamicFormItemNormal
- v-if="item.label"
- :item="item"
- :parent="parent"
- :name="''"
- :rawModel="rawModel"
- :model="null"
- :noLabel="true"
- :disabled="disabled || evaluateCallback(item.disabled)"
- >
- <template #insertion>
- <span v-if="item.label" class="dynamic-form-object-title">{{ evaluateCallback(item.label) }}</span>
- </template>
- </DynamicFormItemNormal>
- <!--循环子条目-->
- <DynamicFormItemContainerFuckMp
- v-for="(child, k) in item.children"
- :key="k"
- :item="child"
- :name="name+'.'+child.name"
- :rawModel="rawModel"
- :model="(finalModel as IDynamicFormObject)[child.name]"
- :parent="item"
- :parentModel="finalModel"
- :parentName="name"
- :isFirst="k === 0"
- :isLast="k === (item.children?.length || 0) - 1"
- @update:model="(v: unknown) => (model as IDynamicFormObject)[child.name] = v"
- :disabled="disabled || evaluateCallback(item.disabled)"
- />
- </DynamicFormCheckEmpty>
- <!--对象组-->
- <DynamicFormCheckEmpty
- v-else-if="item.type === 'object-group'"
- :model="model"
- :modelWithDefault="finalModel"
- :suppressEmptyError="editmode || finalOptions?.suppressEmptyError || item.suppressEmptyError"
- :name="name"
- checkType="object"
- >
- <FormGroup :title="evaluateCallback(item.label)" v-bind="(item.additionalProps as object)">
- <Row v-bind="item.rowProps">
- <!--循环子条目-->
- <DynamicFormItemContainerFuckMp
- v-for="(child, k) in item.children"
- :key="k"
- :item="child"
- :colProps="{ ...item.childrenColProps, ...child.colProps }"
- :name="name+'.'+child.name"
- :rawModel="rawModel"
- :model="((finalModel as IDynamicFormObject)[child.name] as IDynamicFormObject)"
- :parent="item"
- :parentModel="finalModel"
- :parentName="name"
- :isFirst="k === 0"
- :isLast="k === (item.children?.length || 0) - 1"
- @update:model="(v: unknown) => (model as IDynamicFormObject)[child.name] = v"
- :disabled="disabled || evaluateCallback(item.disabled)"
- />
- </Row>
- </FormGroup>
- </DynamicFormCheckEmpty>
- <!--扁平组-->
- <FormGroup v-else-if="item.type === 'flat-group'" :title="evaluateCallback(item.label)" v-bind="(item.additionalProps as object)">
- <Row v-bind="item.rowProps">
- <!--循环子条目-->
- <DynamicFormItemContainerFuckMp
- v-for="(child, k) in item.children"
- :colProps="{ ...item.childrenColProps, ...child.colProps }"
- :key="k"
- :item="child"
- :name="parentName ? `${parentName}.${child.name}` : child.name"
- :rawModel="rawModel"
- :model="((parentModel as IDynamicFormObject)[child.name])"
- :parent="item"
- :parentModel="parentModel"
- :parentName="parentName"
- :isFirst="k === 0"
- :isLast="k === (item.children?.length || 0) - 1"
- @update:model="(v: unknown) => (parentModel as IDynamicFormObject)[child.name] = v"
- :disabled="disabled || evaluateCallback(item.disabled)"
- >
- <template #formCeil="values">
- <slot name="formCeil" :data="values.data" />
- </template>
- </DynamicFormItemContainerFuckMp>
- </Row>
- </FormGroup>
- <!--扁平普通-->
- <DynamicFormItemNormal v-else-if="item.type === 'flat-simple'"
- :item="item"
- :parent="parent"
- :name="name"
- :disabled="disabled || evaluateCallback(item.disabled)"
- :model="(finalModel as IDynamicFormObject)"
- :rawModel="rawModel"
- :parentModel="parentModel"
- :parentName="parentName"
- >
- <template #insertion>
- <Row v-bind="item.rowProps">
- <!--循环子条目-->
- <DynamicFormItemContainerFuckMp
- v-for="(child, k) in item.children"
- :key="k"
- :item="child"
- :colProps="{ ...item.childrenColProps, ...child.colProps }"
- :name="parentName ? `${parentName}.${child.name}` : child.name"
- :rawModel="rawModel"
- :model="((parentModel as IDynamicFormObject)[child.name])"
- :parent="item"
- :parentModel="parentModel"
- :parentName="parentName"
- :isFirst="k === 0"
- :isLast="k === (item.children?.length || 0) - 1"
- @update:model="(v: unknown) => (parentModel as IDynamicFormObject)[child.name] = v"
- :disabled="disabled || evaluateCallback(item.disabled)"
- >
- <template #formCeil="values">
- <slot name="formCeil" :data="values.data" />
- </template>
- </DynamicFormItemContainerFuckMp>
- </Row>
- </template>
- </DynamicFormItemNormal>
- <!--数组变量组-->
- <DynamicFormCheckEmpty
- v-else-if="item.type === 'array-single'"
- :model="model"
- :modelWithDefault="finalModel"
- :suppressEmptyError="editmode || finalOptions?.suppressEmptyError || item.suppressEmptyError"
- :name="name"
- checkType="array"
- >
- <DynamicFormItemNormal
- :item="item"
- :name="name"
- :disabled="disabled || evaluateCallback(item.disabled)"
- :model="(finalModel as IDynamicFormObject)"
- :rawModel="rawModel"
- :parentModel="parentModel"
- :parent="parent"
- :parentName="name"
- >
- <template #insertion>
- <FormArrayGroup
- :model="(finalModel as unknown as unknown[])"
- :item="item"
- :parent="parent"
- :name="name"
- :rawModel="rawModel"
- :isObject="false"
- :addCallback="item.newChildrenObject"
- :deleteCallback="item.deleteChildrenCallback"
- v-bind="(item.additionalProps as IDynamicFormObject)"
- >
- <template #addButton="props">
- <slot name="arrayButtonAdd" :onClick="props.onClick" />
- </template>
- <template #itemButton="props">
- <slot name="arrayButtons"
- :onDeleteClick="props.onDeleteClick"
- :onUpClick="props.onUpClick"
- :onDownClick="props.onDownClick"
- />
- </template>
- <template #child="{ item, pitem, kname, model: child, onUpdateValue, isFirst, isLast }">
- <DynamicFormItemContainerFuckMp
- :item="item"
- :name="kname"
- :rawModel="rawModel"
- :model="child"
- :parent="pitem"
- :parentModel="model"
- :parentName="name"
- :disabled="disabled || evaluateCallback(item.disabled)"
- :isFirst="isFirst"
- :isLast="isLast"
- @update:model="(v: unknown) => onUpdateValue(v)"
- />
- </template>
- </FormArrayGroup>
- </template>
- </DynamicFormItemNormal>
- </DynamicFormCheckEmpty>
- <!--数组对象组-->
- <DynamicFormCheckEmpty
- v-else-if="item.type === 'array-object'"
- :model="model"
- :modelWithDefault="finalModel"
- :suppressEmptyError="editmode || finalOptions?.suppressEmptyError || item.suppressEmptyError"
- :name="name"
- checkType="array"
- >
- <DynamicFormItemNormal
- :item="item"
- :parent="parent"
- :name="name"
- :disabled="disabled || evaluateCallback(item.disabled)"
- :model="finalModel"
- :rawModel="rawModel"
- :parentModel="parentModel"
- :parentName="parentName"
- :isFirst="isFirst"
- :isLast="isLast"
- >
- <template #insertion>
- <FormArrayGroup
- :model="(finalModel as unknown as unknown[])"
- :item="item"
- :parent="parent"
- :name="name"
- :rawModel="rawModel"
- :isObject="true"
- :addCallback="item.newChildrenObject"
- :deleteCallback="item.deleteChildrenCallback"
- v-bind="(item.additionalProps as IDynamicFormObject)"
- >
- <template #addButton="props">
- <slot name="arrayButtonAdd" :onClick="props.onClick" />
- </template>
- <template #itemButton="props">
- <slot name="arrayButtons"
- :onDeleteClick="props.onDeleteClick"
- :onUpClick="props.onUpClick"
- :onDownClick="props.onDownClick"
- />
- </template>
- <template #child="{ item, pitem, kname, model: child, onUpdateValue, isFirst, isLast }">
- <DynamicFormItemContainerFuckMp
- :item="item"
- :name="kname"
- :rawModel="rawModel"
- :model="child"
- :parent="pitem"
- :parentModel="model"
- :parentName="name"
- :isFirst="isFirst"
- :isLast="isLast"
- :disabled="disabled || evaluateCallback(item.disabled)"
- @update:model="(v: unknown) => onUpdateValue(v)"
- />
- </template>
- </FormArrayGroup>
- </template>
- </DynamicFormItemNormal>
- </DynamicFormCheckEmpty>
- <!--正常条目-->
- <DynamicFormItemNormal
- v-else
- :item="item"
- :parent="parent"
- :name="name"
- :disabled="disabled || evaluateCallback(item.disabled)"
- :rawModel="rawModel"
- :parentModel="parentModel"
- :model="finalModel"
- :isFirst="isFirst"
- :isLast="isLast"
- @update:model="(v: unknown) => $emit('update:model', v)"
- >
- <template #formCeil="values">
- <slot name="formCeil" :data="values.data" />
- </template>
- </DynamicFormItemNormal>
- </Col>
- </template>
- <script lang="ts" setup>
- import { inject, type Ref, toRefs, computed, provide } from 'vue';
- import type { Rules } from 'async-validator';
- import type { IDynamicFormItem, IDynamicFormItemCallback, IDynamicFormObject, IDynamicFormOptions, IDynamicFormRef, IEvaluateCallback } from '..';
- import DynamicFormItemNormal, { type FormCeilProps } from '../DynamicFormControl.vue';
- import FormGroup from '../group/FormGroup.vue';
- import FormArrayGroup from '../group/FormArrayGroup.vue';;
- import Col, { type ColProps } from '@/components/layout/grid/Col.vue';
- import Row from '@/components/layout/grid/Row.vue';
- import DynamicFormCheckEmpty from './DynamicFormCheckEmpty.vue';
- import DynamicFormItemContainerFuckMp from './DynamicFormItemContainerFuckMp.vue';
- /**
- * 动态表单条目包装组件,处理基础类型分支、数据传入、回调处理、事件传递。
- */
- export interface DynamicFormItemContainerProps {
- item: IDynamicFormItem;
- name: string;
- disabled?: boolean;
- model?: any;
- rawModel?: IDynamicFormObject;
- parent?: IDynamicFormItem;
- parentModel?: unknown;
- parentName?: string;
- colProps?: ColProps;
- isFirst?: boolean;
- isLast: boolean;
- }
- const props = withDefaults(defineProps<DynamicFormItemContainerProps>(), {
- isFirst: false,
- isLast: false,
- });
- const containerTypes = ['object', 'object-group', 'array-single','group-array','flat-simple','flat-group'];
- const isContainer = computed(() => props.item.type && containerTypes.includes(props.item.type));
- defineEmits([ 'update:model' ]);
- defineSlots<{
- formCeil(props: {
- data: FormCeilProps;
- }): any,
- arrayButtonAdd(props: {
- onClick: () => void;
- }): any,
- arrayButtons(props: {
- onDeleteClick: () => void;
- onUpClick: () => void;
- onDownClick: () => void;
- }): any,
- }>()
- const propsP = toRefs(props);
- const finalOptions = inject<Ref<IDynamicFormOptions>>('finalOptions');
- const globalParams = inject<Ref<IDynamicFormObject>>('globalParams');
- const formRef = inject<IDynamicFormRef>('formRef');
- const editmode = inject('editmode', false);
- const formName = inject('formName', '')
- //判断是否显示当前条目
- const isShow = computed(() => props.item.show === undefined || evaluateCallback(props.item.show));
- //处理默认值
- const finalModel = computed(() => {
- const val = props.model
- if (val !== undefined && val !== null)
- return props.model;
- if (props.item.defaultValue) {
- if (typeof props.item.defaultValue === 'function')
- return props.item.defaultValue();
- return props.item.defaultValue;
- }
- return null;
- });
- //处理回调函数
- function evaluateCallback<T>(val: T|IDynamicFormItemCallback<T>) {
- if (typeof val === 'object' && typeof (val as IDynamicFormItemCallback<T>).callback === 'function')
- return (val as IDynamicFormItemCallback<T>).callback(
- finalModel.value,
- propsP.rawModel.value,
- propsP.parentModel?.value,
- {
- item: propsP.item.value,
- form: formRef!,
- formGlobalParams: globalParams?.value || {},
- formRules: (finalOptions?.value.formRules ?? {}) as Record<string, Rules>,
- isFirst: propsP.isFirst.value,
- isLast: propsP.isLast.value,
- }
- );
- return val as T;
- }
- provide<IEvaluateCallback>('evaluateCallback', evaluateCallback);
- defineOptions({
- name: 'DynamicFormItemContainer',
- options: {
- virtualHost: true,
- styleIsolation: 'shared',
- }
- })
- </script>
- <style lang="scss">
- .dynamic-form-item-wrapper {
- position: relative;
- }
- </style>
|