| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- <template>
- <text
- v-if="item.type === 'static-text' "
- class="form-static-text"
- :style="(params.style as any)"
- :class="(params.class as any)"
- >
- {{ params?.text ?? model ?? null }}
- </text>
- <Field
- ref="formItemRef"
- v-else-if="item.type && filedInternalTypes.includes(item.type)"
- :label="label"
- :multiline="item.type === 'textarea'"
- :tags="item.type.endsWith('-tag')"
- :name="item.name"
- :modelValue="model"
- @update:modelValue="onValueChanged"
- :maxlength="260"
- :showBottomBorder="!isLast"
- :required="Boolean(item.rules?.length)"
- :rules="item.rules"
- :disabled="disabled"
- :readonly="readonly"
- v-bind="{
- ...params,
- ...extraDefine?.itemProps || {},
- ...item.formProps,
- }"
- />
- <Field
- v-else
- ref="formItemRef"
- :label="label"
- :name="item.name"
- :required="Boolean(item.rules?.length)"
- :showRightArrow="extraDefine?.needArrow"
- :showBottomBorder="!isLast"
- :requireChildRef="() => itemRef"
- :rules="item.rules"
- :disabled="disabled"
- :readonly="readonly"
- v-bind="{
- ...extraDefine?.itemProps || {},
- ...item.formProps,
- }"
- >
- <!-- <text>fullName: {{item.name}}</text> -->
- <slot name="insertion">
- <template v-if="item.type === 'custom'">
- <slot name="formCeil" :data="data" />
- </template>
- <template v-else-if="item.type === 'number'">
- <Stepper
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'switch'">
- <Switch
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'radio-value'">
- <RadioValue
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as RadioValueProps)"
- />
- </template>
- <template v-else-if="item.type === 'radio-id'">
- <RadioIdField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as RadioIdFieldProps)"
- />
- </template>
- <template v-else-if="item.type === 'select'">
- <view>
- <NaPickerField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as PickerFieldProps)"
- />
- </view>
- </template>
- <template v-else-if="item.type === 'rate'">
- <Rate
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as RateProps)"
- />
- </template>
- <template v-else-if="item.type === 'uploader'">
- <UploaderField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled"
- :readonly="readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as UploaderFieldProps)"
- />
- </template>
- <template v-else-if="item.type === 'select-id'">
- <PickerIdField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled"
- :readonly="readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as PickerIdFieldProps)"
- />
- </template>
- <template v-else-if="item.type === 'select-city'">
- <PickerCityField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled"
- :readonly="readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any)"
- />
- </template>
- <template v-else-if="item.type === 'select-address'">
- <PickerAddressField
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled"
- :readonly="readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any)"
- />
- </template>
- <template v-else-if="item.type === 'select-lonlat'">
- <PickerLonlat
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="(v:any) => onValueChanged(v)"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'check-box'">
- <CheckBox
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'check-box-list'">
- <CheckBoxList
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params)"
- />
- </template>
- <template v-else-if="item.type === 'check-box-tree'">
- <CheckBoxTreeList
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="(params as any as CheckBoxTreeListProps)"
- />
- </template>
- <template v-else-if="item.type === 'check-box-int'">
- <CheckBoxToInt
- ref="itemRef"
- :modelValue="model"
- :disabled="disabled || readonly"
- @update:modelValue="onValueChanged"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'datetime'">
- <view>
- <DateTimePickerField
- ref="itemRef"
- :modelValue="model"
- v-bind="params"
- @update:modelValue="(e: any) => onValueChanged(e)"
- />
- </view>
- </template>
- <template v-else-if="item.type === 'time'">
- <view>
- <TimePickerField
- ref="itemRef"
- :modelValue="model"
- v-bind="params"
- @update:modelValue="(e: any) => onValueChanged(e)"
- />
- </view>
- </template>
- <template v-else-if="item.type === 'date'">
- <view>
- <DatePickerField
- ref="itemRef"
- :modelValue="model"
- v-bind="params"
- @update:modelValue="(e: any) => onValueChanged(e)"
- />
- </view>
- </template>
- <template v-else-if="item.type === 'button'">
- <Button
- ref="itemRef"
- :disabled="disabled || readonly"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'image'">
- <Image
- ref="itemRef"
- v-bind="params"
- />
- </template>
- <template v-else-if="item.type === 'alert'">
- <Alert
- ref="itemRef"
- v-bind="params"
- />
- </template>
- <ComponentRender v-else
- ref="itemRef"
- :modelValue="model"
- @update:modelValue="onValueChanged"
- :params="params"
- :item="item"
- :name="name"
- :isLast="isLast"
- :disabled="disabled"
- :readonly="readonly"
- />
- </slot>
- </Field>
- </template>
- <script setup lang="ts">
- import { computed, inject, onBeforeUnmount, onMounted, ref, type PropType, type Ref } from 'vue';
- import type { IDynamicFormItem, IDynamicFormItemCallback, IDynamicFormMessageCenter, IDynamicFormObject, IDynamicFormOptions, IDynamicFormRef } from '.';
- import Field from '../form/Field.vue';
- import Stepper from '../form/Stepper.vue';
- import NaPickerField, { type PickerFieldProps } from '../form/PickerField.vue';
- import CheckBox from '../form/CheckBox.vue';
- import Switch from '../form/Switch.vue';
- import RadioValue from './wrappers/RadioValue.vue';
- import PickerIdField from './wrappers/PickerIdField.vue';
- import CheckBoxList from './wrappers/CheckBoxList.vue';
- import CheckBoxToInt from './wrappers/CheckBoxToInt.vue';
- import type { RadioValueProps } from './wrappers/RadioValue';
- import type { PickerIdFieldProps } from './wrappers/PickerIdField';
- import PickerCityField from './wrappers/PickerCityField.vue';
- import PickerLonlat from './wrappers/PickerLonlat.vue';
- import DateTimePickerField from '../form/DateTimePickerField.vue';
- import TimePickerField from '../form/TimePickerField.vue';
- import DatePickerField from '../form/DatePickerField.vue';
- import UploaderField, { type UploaderFieldProps } from '../form/UploaderField.vue';
- import RadioIdField from './wrappers/RadioIdField.vue';
- import type { RadioIdFieldProps } from './wrappers/RadioIdField';
- import Rate, { type RateProps } from '../form/Rate.vue';
- import ComponentConfigs from '@/common/components/dynamicf/ComponentConfigs';
- import ComponentRender from '@/common/components/dynamicf/ComponentRender.vue';
- import type { Rules } from 'async-validator';
- import PickerAddressField from './wrappers/PickerAddressField.vue';
- import Button from '../basic/Button.vue';
- import Alert from '../feedback/Alert.vue';
- import Image from '../basic/Image.vue';
- import CheckBoxTreeList, { type CheckBoxTreeListProps } from './wrappers/CheckBoxTreeList.vue';
- import { useInjectFormContext, useInjectFormItemContext } from '../form/FormContext';
- export interface FormCeilProps {
- model: unknown,
- rawModel: unknown,
- parent?: IDynamicFormItem,
- parentModel: unknown,
- onModelUpdate: (v: unknown) => void,
- item: IDynamicFormItem,
- name: string,
- disabled: boolean,
- additionalProps: Record<string, unknown>,
- }
- const filedInternalTypes = [
- 'text',
- 'textarea',
- 'text-tag',
- ]
- const props = defineProps({
- item: {
- type: Object as PropType<IDynamicFormItem>,
- required: true,
- },
- name: {
- type: String,
- default: ''
- },
- parent: {
- type: Object as PropType<IDynamicFormItem>,
- default: null
- },
- disabled: {
- type: Boolean,
- default: false
- },
- model: {
- type: null
- },
- parentModel: {
- type: null
- },
- rawModel: {
- type: Object as PropType<Record<string, unknown>>,
- default: null
- },
- noLabel: {
- type: Boolean,
- default: false
- },
- formWrapperColDefault: {
- type: Object,
- default: null
- },
- formLabelColDefault: {
- type: Object,
- default: null
- },
- isFirst: {
- type: Boolean,
- default: false,
- },
- isLast: {
- type: Boolean,
- default: false,
- },
- });
- const emit = defineEmits([ 'update:model' ]);
- const formItemRef = ref();
- const finalOptions = inject<Ref<IDynamicFormOptions>>('finalOptions');
- const globalParams = inject<Ref<IDynamicFormObject>>('globalParams');
- const formRef = inject<IDynamicFormRef>('formRef');
- const formName = inject('formName', '');
- const context = useInjectFormItemContext();
- const formContext = useInjectFormContext();
- const disabled = computed(() => props.disabled || formContext?.disabled.value || context?.disabled.value);
- const readonly = computed(() => formContext?.readonly.value || context?.readonly.value);
- function evaluateCallback(val: unknown|IDynamicFormItemCallback<unknown>) {
- if (typeof val === 'object' && typeof (val as IDynamicFormItemCallback<unknown>).callback === 'function')
- return (val as IDynamicFormItemCallback<unknown>).callback(
- props.model,
- props.rawModel,
- props.parentModel,
- {
- item: props.item,
- parent: props.parent,
- form: formRef!,
- formGlobalParams: globalParams?.value || {},
- formRules: (finalOptions?.value.formRules ?? {}) as Record<string, Rules>,
- isFirst: props.isFirst,
- isLast: props.isLast,
- }
- );
- return val as unknown;
- }
- function evaluateCallbackObj(val: Record<string, unknown|IDynamicFormItemCallback<unknown>>) {
- const newObj = {} as Record<string, unknown>;
- for (const key in val) {
- if (Object.prototype.hasOwnProperty.call(val, key))
- newObj[key] = evaluateCallback(val[key]);
- }
- return newObj;
- }
- const extraDefine = computed(() => ComponentConfigs.find((item) => item.name === props.item.type))
- const params = computed(() => {
- return {
- ...extraDefine.value?.props || {},
- ...evaluateCallbackObj(props.item.additionalProps as any)
- } as Record<string, unknown>
- })
- const label = computed(() => evaluateCallback(props.item.label) as string)
- const data = computed<FormCeilProps>(() => {
- return {
- name: props.name,
- item: props.item,
- model: props.model,
- onModelUpdate: onValueChanged,
- rawModel: props.rawModel,
- parentModel: props.parentModel,
- parent: props.parent,
- rules: props.item.rules,
- disabled: props.disabled,
- additionalProps: props.item.additionalProps as Record<string, unknown>,
- }
- })
- const itemRef = ref();
- const messageCenter = inject<IDynamicFormMessageCenter>('messageCenter');
-
- function onValueChanged(v: any) {
- props.item.watch?.(props.model, v, props.rawModel, getComponentRef());
- emit('update:model', v);
- }
- function getComponentRef() {
- if (typeof itemRef.value.getItemRef === 'function')
- return itemRef.value.getItemRef();
- return itemRef.value;
- }
- onMounted(() => {
- props.item.mounted?.(props.model, props.rawModel, getComponentRef());
- messageCenter?.addWidgetRef(props.item.name, props.item.type ?? '', getComponentRef);
- })
- onBeforeUnmount(() => {
- props.item.beforeUnmount?.(props.model, props.rawModel, getComponentRef());
- messageCenter?.removeWidgetRef(props.item.name, props.item.type ?? '', getComponentRef);
- })
- defineOptions({
- options: {
- virtualHost: true,
- }
- })
- </script>
|