mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 10:49:51 +08:00 
			
		
		
		
	feat(form): 支持表单差异对比
1、支持表单差异对比 2、支持在tab统计差异数量
This commit is contained in:
		
							parent
							
								
									c41af9d01d
								
							
						
					
					
						commit
						6610f30afd
					
				@ -158,6 +158,9 @@ watch(
 | 
			
		||||
    services?.codeBlockService.refreshAllRelations();
 | 
			
		||||
    refreshCodeList();
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    immediate: true,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
watch(
 | 
			
		||||
 | 
			
		||||
@ -53,8 +53,7 @@
 | 
			
		||||
      padding: 5px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .is-text,
 | 
			
		||||
    i {
 | 
			
		||||
    .is-text > i {
 | 
			
		||||
      color: $--font-color;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,8 @@
 | 
			
		||||
        :key="item[keyProp] ?? index"
 | 
			
		||||
        :config="item"
 | 
			
		||||
        :model="values"
 | 
			
		||||
        :last-values="lastValuesProcessed"
 | 
			
		||||
        :is-compare="isCompare"
 | 
			
		||||
        :label-width="item.labelWidth || labelWidth"
 | 
			
		||||
        :step-active="stepActive"
 | 
			
		||||
        :size="size"
 | 
			
		||||
@ -26,8 +28,8 @@
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts" name="MForm">
 | 
			
		||||
import { provide, reactive, ref, toRaw, watch, watchEffect } from 'vue';
 | 
			
		||||
import { isEqual } from 'lodash-es';
 | 
			
		||||
import cloneDeep from 'lodash-es/cloneDeep';
 | 
			
		||||
import isEqual from 'lodash-es/isEqual';
 | 
			
		||||
 | 
			
		||||
import { TMagicForm } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
@ -38,8 +40,14 @@ import type { FormConfig, FormState, FormValue, ValidateError } from './schema';
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    /** 表单配置 */
 | 
			
		||||
    config: FormConfig;
 | 
			
		||||
    /** 表单值 */
 | 
			
		||||
    initValues: Object;
 | 
			
		||||
    /** 需对比的值(开启对比模式时传入) */
 | 
			
		||||
    lastValues?: Object;
 | 
			
		||||
    /** 是否开启对比模式 */
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    parentValues?: Object;
 | 
			
		||||
    labelWidth?: string;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
@ -54,6 +62,8 @@ const props = withDefaults(
 | 
			
		||||
  {
 | 
			
		||||
    config: () => [],
 | 
			
		||||
    initValues: () => ({}),
 | 
			
		||||
    lastValues: () => ({}),
 | 
			
		||||
    isCompare: false,
 | 
			
		||||
    parentValues: () => ({}),
 | 
			
		||||
    labelWidth: '200px',
 | 
			
		||||
    disabled: false,
 | 
			
		||||
@ -70,6 +80,7 @@ const emit = defineEmits(['change', 'field-input', 'field-change']);
 | 
			
		||||
const tMagicForm = ref<InstanceType<typeof TMagicForm>>();
 | 
			
		||||
const initialized = ref(false);
 | 
			
		||||
const values = ref<FormValue>({});
 | 
			
		||||
const lastValuesProcessed = ref<FormValue>({});
 | 
			
		||||
const fields = new Map<string, any>();
 | 
			
		||||
 | 
			
		||||
const requestFuc = getConfig('request') as Function;
 | 
			
		||||
@ -79,8 +90,11 @@ const formState: FormState = reactive<FormState>({
 | 
			
		||||
  popperClass: props.popperClass,
 | 
			
		||||
  config: props.config,
 | 
			
		||||
  initValues: props.initValues,
 | 
			
		||||
  isCompare: props.isCompare,
 | 
			
		||||
  lastValues: props.lastValues,
 | 
			
		||||
  parentValues: props.parentValues,
 | 
			
		||||
  values,
 | 
			
		||||
  lastValuesProcessed,
 | 
			
		||||
  $emit: emit as (event: string, ...args: any[]) => void,
 | 
			
		||||
  fields,
 | 
			
		||||
  setField: (prop: string, field: any) => fields.set(prop, field),
 | 
			
		||||
@ -98,6 +112,8 @@ const formState: FormState = reactive<FormState>({
 | 
			
		||||
 | 
			
		||||
watchEffect(() => {
 | 
			
		||||
  formState.initValues = props.initValues;
 | 
			
		||||
  formState.lastValues = props.lastValues;
 | 
			
		||||
  formState.isCompare = props.isCompare;
 | 
			
		||||
  formState.config = props.config;
 | 
			
		||||
  formState.keyProp = props.keyProp;
 | 
			
		||||
  formState.popperClass = props.popperClass;
 | 
			
		||||
@ -118,8 +134,20 @@ watch(
 | 
			
		||||
      config: props.config,
 | 
			
		||||
    }).then((value) => {
 | 
			
		||||
      values.value = value;
 | 
			
		||||
      initialized.value = true;
 | 
			
		||||
      // 非对比模式,初始化完成
 | 
			
		||||
      initialized.value = !props.isCompare;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if (props.isCompare) {
 | 
			
		||||
      // 对比模式下初始化待对比的表单值
 | 
			
		||||
      initValue(formState, {
 | 
			
		||||
        initValues: props.lastValues,
 | 
			
		||||
        config: props.config,
 | 
			
		||||
      }).then((value) => {
 | 
			
		||||
        lastValuesProcessed.value = value;
 | 
			
		||||
        initialized.value = true;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  { immediate: true },
 | 
			
		||||
);
 | 
			
		||||
@ -130,6 +158,7 @@ const changeHandler = () => {
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
  values,
 | 
			
		||||
  lastValuesProcessed,
 | 
			
		||||
  formState,
 | 
			
		||||
  initialized,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
  <TMagicCol v-show="display && config.type !== 'hidden'" :span="span">
 | 
			
		||||
    <Container
 | 
			
		||||
      :model="model"
 | 
			
		||||
      :lastValues="lastValues"
 | 
			
		||||
      :is-compare="isCompare"
 | 
			
		||||
      :config="config"
 | 
			
		||||
      :prop="prop"
 | 
			
		||||
      :label-width="config.labelWidth || labelWidth"
 | 
			
		||||
@ -9,6 +11,7 @@
 | 
			
		||||
      :size="size"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      @change="changeHandler"
 | 
			
		||||
      @add-diff-count="onAddDiffCount"
 | 
			
		||||
    ></Container>
 | 
			
		||||
  </TMagicCol>
 | 
			
		||||
</template>
 | 
			
		||||
@ -25,6 +28,8 @@ import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  lastValues?: any;
 | 
			
		||||
  isCompare?: boolean;
 | 
			
		||||
  config: ChildConfig;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
  expandMore?: boolean;
 | 
			
		||||
@ -34,9 +39,10 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const display = computed(() => displayFunction(mForm, props.config.display, props));
 | 
			
		||||
const changeHandler = () => emit('change', props.model);
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,8 @@
 | 
			
		||||
      :size="size"
 | 
			
		||||
      :is="tagName"
 | 
			
		||||
      :model="model"
 | 
			
		||||
      :last-values="lastValues"
 | 
			
		||||
      :is-compare="isCompare"
 | 
			
		||||
      :config="config"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      :name="name"
 | 
			
		||||
@ -28,15 +30,120 @@
 | 
			
		||||
      :expand-more="expand"
 | 
			
		||||
      :label-width="itemLabelWidth"
 | 
			
		||||
      @change="onChangeHandler"
 | 
			
		||||
      @addDiffCount="onAddDiffCount"
 | 
			
		||||
    ></component>
 | 
			
		||||
 | 
			
		||||
    <template v-else-if="type && display">
 | 
			
		||||
    <template v-else-if="type && display && !showDiff">
 | 
			
		||||
      <TMagicFormItem
 | 
			
		||||
        :style="config.tip ? 'flex: 1' : ''"
 | 
			
		||||
        :class="{ hidden: `${itemLabelWidth}` === '0' || !config.text }"
 | 
			
		||||
        :prop="itemProp"
 | 
			
		||||
        :label-width="itemLabelWidth"
 | 
			
		||||
        :rules="rule"
 | 
			
		||||
      >
 | 
			
		||||
        <template #label><span v-html="type === 'checkbox' ? '' : config.text"></span></template>
 | 
			
		||||
        <TMagicTooltip v-if="tooltip">
 | 
			
		||||
          <component
 | 
			
		||||
            :key="key(config)"
 | 
			
		||||
            :size="size"
 | 
			
		||||
            :is="tagName"
 | 
			
		||||
            :model="model"
 | 
			
		||||
            :config="config"
 | 
			
		||||
            :name="name"
 | 
			
		||||
            :disabled="disabled"
 | 
			
		||||
            :prop="itemProp"
 | 
			
		||||
            @change="onChangeHandler"
 | 
			
		||||
            @addDiffCount="onAddDiffCount"
 | 
			
		||||
          ></component>
 | 
			
		||||
          <template #content>
 | 
			
		||||
            <div v-html="tooltip"></div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </TMagicTooltip>
 | 
			
		||||
 | 
			
		||||
        <component
 | 
			
		||||
          v-else
 | 
			
		||||
          :key="key(config)"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :is="tagName"
 | 
			
		||||
          :model="model"
 | 
			
		||||
          :config="config"
 | 
			
		||||
          :name="name"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :prop="itemProp"
 | 
			
		||||
          @change="onChangeHandler"
 | 
			
		||||
          @addDiffCount="onAddDiffCount"
 | 
			
		||||
        ></component>
 | 
			
		||||
 | 
			
		||||
        <div v-if="extra" v-html="extra" class="m-form-tip"></div>
 | 
			
		||||
      </TMagicFormItem>
 | 
			
		||||
 | 
			
		||||
      <TMagicTooltip v-if="config.tip" placement="left">
 | 
			
		||||
        <TMagicIcon style="line-height: 40px; margin-left: 5px"><warning-filled /></TMagicIcon>
 | 
			
		||||
        <template #content>
 | 
			
		||||
          <div v-html="config.tip"></div>
 | 
			
		||||
        </template>
 | 
			
		||||
      </TMagicTooltip>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
    <!-- 对比 -->
 | 
			
		||||
    <template v-else-if="type && display && showDiff">
 | 
			
		||||
      <!-- 上次内容 -->
 | 
			
		||||
      <TMagicFormItem
 | 
			
		||||
        :style="config.tip ? 'flex: 1' : ''"
 | 
			
		||||
        :class="{ hidden: `${itemLabelWidth}` === '0' || !config.text }"
 | 
			
		||||
        :prop="itemProp"
 | 
			
		||||
        :label-width="itemLabelWidth"
 | 
			
		||||
        :rules="rule"
 | 
			
		||||
        style="background: #f7dadd"
 | 
			
		||||
      >
 | 
			
		||||
        <template #label><span v-html="type === 'checkbox' ? '' : config.text"></span></template>
 | 
			
		||||
        <TMagicTooltip v-if="tooltip">
 | 
			
		||||
          <component
 | 
			
		||||
            :key="key(config)"
 | 
			
		||||
            :size="size"
 | 
			
		||||
            :is="tagName"
 | 
			
		||||
            :model="lastValues"
 | 
			
		||||
            :config="config"
 | 
			
		||||
            :name="name"
 | 
			
		||||
            :disabled="disabled"
 | 
			
		||||
            :prop="itemProp"
 | 
			
		||||
            @change="onChangeHandler"
 | 
			
		||||
          ></component>
 | 
			
		||||
          <template #content>
 | 
			
		||||
            <div v-html="tooltip"></div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </TMagicTooltip>
 | 
			
		||||
 | 
			
		||||
        <component
 | 
			
		||||
          v-else
 | 
			
		||||
          :key="key(config)"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :is="tagName"
 | 
			
		||||
          :model="lastValues"
 | 
			
		||||
          :config="config"
 | 
			
		||||
          :name="name"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :prop="itemProp"
 | 
			
		||||
          @change="onChangeHandler"
 | 
			
		||||
        ></component>
 | 
			
		||||
 | 
			
		||||
        <div v-if="extra" v-html="extra" class="m-form-tip"></div>
 | 
			
		||||
      </TMagicFormItem>
 | 
			
		||||
 | 
			
		||||
      <TMagicTooltip v-if="config.tip" placement="left">
 | 
			
		||||
        <TMagicIcon style="line-height: 40px; margin-left: 5px"><warning-filled /></TMagicIcon>
 | 
			
		||||
        <template #content>
 | 
			
		||||
          <div v-html="config.tip"></div>
 | 
			
		||||
        </template>
 | 
			
		||||
      </TMagicTooltip>
 | 
			
		||||
      <!-- 当前内容 -->
 | 
			
		||||
      <TMagicFormItem
 | 
			
		||||
        :style="config.tip ? 'flex: 1' : ''"
 | 
			
		||||
        :class="{ hidden: `${itemLabelWidth}` === '0' || !config.text }"
 | 
			
		||||
        :prop="itemProp"
 | 
			
		||||
        :label-width="itemLabelWidth"
 | 
			
		||||
        :rules="rule"
 | 
			
		||||
        style="background: #def7da"
 | 
			
		||||
      >
 | 
			
		||||
        <template #label><span v-html="type === 'checkbox' ? '' : config.text"></span></template>
 | 
			
		||||
        <TMagicTooltip v-if="tooltip">
 | 
			
		||||
@ -86,6 +193,8 @@
 | 
			
		||||
          v-for="item in items"
 | 
			
		||||
          :key="key(item)"
 | 
			
		||||
          :model="name || name === 0 ? model[name] : model"
 | 
			
		||||
          :last-values="name || name === 0 ? lastValues[name] : lastValues"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
@ -94,6 +203,7 @@
 | 
			
		||||
          :label-width="itemLabelWidth"
 | 
			
		||||
          :prop="itemProp"
 | 
			
		||||
          @change="onChangeHandler"
 | 
			
		||||
          @addDiffCount="onAddDiffCount"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </template>
 | 
			
		||||
    </template>
 | 
			
		||||
@ -107,8 +217,9 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts" name="MFormContainer">
 | 
			
		||||
import { computed, inject, ref, resolveComponent, watchEffect } from 'vue';
 | 
			
		||||
import { computed, inject, ref, resolveComponent, watch, watchEffect } from 'vue';
 | 
			
		||||
import { WarningFilled } from '@element-plus/icons-vue';
 | 
			
		||||
import { isEqual } from 'lodash-es';
 | 
			
		||||
 | 
			
		||||
import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from '@tmagic/design';
 | 
			
		||||
 | 
			
		||||
@ -117,7 +228,10 @@ import { display as displayFunction, filterFunction, getRules } from '../utils/f
 | 
			
		||||
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    /** 表单值 */
 | 
			
		||||
    model: FormValue;
 | 
			
		||||
    /** 需对比的值(开启对比模式时传入) */
 | 
			
		||||
    lastValues?: FormValue;
 | 
			
		||||
    config: ChildConfig;
 | 
			
		||||
    prop?: string;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
@ -125,15 +239,19 @@ const props = withDefaults(
 | 
			
		||||
    expandMore?: boolean;
 | 
			
		||||
    stepActive?: string | number;
 | 
			
		||||
    size?: string;
 | 
			
		||||
    /** 是否开启对比模式 */
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
  }>(),
 | 
			
		||||
  {
 | 
			
		||||
    prop: '',
 | 
			
		||||
    size: 'small',
 | 
			
		||||
    expandMore: false,
 | 
			
		||||
    lastValues: () => ({}),
 | 
			
		||||
    isCompare: false,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -141,6 +259,14 @@ const expand = ref(false);
 | 
			
		||||
 | 
			
		||||
const name = computed(() => props.config.name || '');
 | 
			
		||||
 | 
			
		||||
// 是否展示两个版本的对比内容
 | 
			
		||||
const showDiff = computed(() => {
 | 
			
		||||
  if (!props.isCompare) return false;
 | 
			
		||||
  const curValue = name.value ? props.model[name.value] : props.model;
 | 
			
		||||
  const lastValue = name.value ? props.lastValues[name.value] : props.lastValues;
 | 
			
		||||
  return !isEqual(curValue, lastValue);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const items = computed(() => (props.config as ContainerCommonConfig).items);
 | 
			
		||||
 | 
			
		||||
const itemProp = computed(() => {
 | 
			
		||||
@ -196,6 +322,21 @@ watchEffect(() => {
 | 
			
		||||
  expand.value = props.expandMore;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 监听是否展示对比内容,如果出现差异项则触发差异数计数事件
 | 
			
		||||
watch(
 | 
			
		||||
  showDiff,
 | 
			
		||||
  (showDiff) => {
 | 
			
		||||
    if (type.value === 'hidden') return;
 | 
			
		||||
    if (items.value && !props.config.text && type.value && display.value) return;
 | 
			
		||||
    if (display.value && showDiff && type.value) {
 | 
			
		||||
      emit('addDiffCount');
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    immediate: true,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const expandHandler = () => (expand.value = !expand.value);
 | 
			
		||||
 | 
			
		||||
const key = (config: any) => config[mForm?.keyProps];
 | 
			
		||||
@ -236,6 +377,9 @@ const trimHandler = (trim: any, value: FormValue | number | string) => {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 继续抛出给更高层级的组件
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
const onChangeHandler = async function (v: FormValue, key?: string) {
 | 
			
		||||
  const { filter, onChange, trim, name, dynamicKey } = props.config as any;
 | 
			
		||||
  let value: FormValue | number | string = v;
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,8 @@
 | 
			
		||||
          v-for="(item, index) in config.items"
 | 
			
		||||
          :key="key(item, index)"
 | 
			
		||||
          :model="name ? model[name] : model"
 | 
			
		||||
          :lastValues="name ? lastValues[name] : lastValues"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :rules="name ? rules[name] : []"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :prop="prop"
 | 
			
		||||
@ -31,6 +33,7 @@
 | 
			
		||||
          :labelWidth="lWidth"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          @change="change"
 | 
			
		||||
          @add-diff-count="onAddDiffCount()"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -42,6 +45,8 @@
 | 
			
		||||
        v-for="(item, index) in config.items"
 | 
			
		||||
        :key="key(item, index)"
 | 
			
		||||
        :model="name ? model[name] : model"
 | 
			
		||||
        :lastValues="name ? lastValues[name] : lastValues"
 | 
			
		||||
        :is-compare="isCompare"
 | 
			
		||||
        :rules="name ? rules[name] : []"
 | 
			
		||||
        :config="item"
 | 
			
		||||
        :prop="prop"
 | 
			
		||||
@ -49,6 +54,7 @@
 | 
			
		||||
        :size="size"
 | 
			
		||||
        :disabled="disabled"
 | 
			
		||||
        @change="change"
 | 
			
		||||
        @addDiffCount="onAddDiffCount()"
 | 
			
		||||
      ></Container>
 | 
			
		||||
    </template>
 | 
			
		||||
  </fieldset>
 | 
			
		||||
@ -69,6 +75,8 @@ const props = withDefaults(
 | 
			
		||||
    prop: string;
 | 
			
		||||
    size?: string;
 | 
			
		||||
    model: Record<string, any>;
 | 
			
		||||
    lastValues?: Record<string, any>;
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    config: FieldsetConfig;
 | 
			
		||||
    rules?: any;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
@ -76,10 +84,12 @@ const props = withDefaults(
 | 
			
		||||
  {
 | 
			
		||||
    rules: {},
 | 
			
		||||
    prop: '',
 | 
			
		||||
    lastValues: () => ({}),
 | 
			
		||||
    isCompare: false,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -113,4 +123,5 @@ if (props.config.checkbox && name.value) {
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@
 | 
			
		||||
      v-for="(item, index) in model[name]"
 | 
			
		||||
      :key="index"
 | 
			
		||||
      :model="item"
 | 
			
		||||
      :lastValues="getLastValues(lastValues[name], index)"
 | 
			
		||||
      :is-compare="isCompare"
 | 
			
		||||
      :config="config"
 | 
			
		||||
      :prop="prop"
 | 
			
		||||
      :index="index"
 | 
			
		||||
@ -20,6 +22,7 @@
 | 
			
		||||
      @remove-item="removeHandler"
 | 
			
		||||
      @swap-item="swapHandler"
 | 
			
		||||
      @change="changeHandler"
 | 
			
		||||
      @addDiffCount="onAddDiffCount()"
 | 
			
		||||
    ></MFieldsGroupListItem>
 | 
			
		||||
 | 
			
		||||
    <TMagicButton @click="addHandler" size="small" :disabled="disabled" v-if="addable">添加组</TMagicButton>
 | 
			
		||||
@ -41,6 +44,8 @@ import MFieldsGroupListItem from './GroupListItem.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  lastValues?: any;
 | 
			
		||||
  isCompare?: boolean;
 | 
			
		||||
  config: GroupListConfig;
 | 
			
		||||
  name: string;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
@ -49,7 +54,7 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -123,4 +128,7 @@ const toggleMode = () => {
 | 
			
		||||
      text: null,
 | 
			
		||||
    }))) as any;
 | 
			
		||||
};
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
const getLastValues = (item: any, index: number) => item?.[index] || {};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -32,11 +32,14 @@
 | 
			
		||||
      v-if="expand"
 | 
			
		||||
      :config="rowConfig"
 | 
			
		||||
      :model="model"
 | 
			
		||||
      :lastValues="lastValues"
 | 
			
		||||
      :is-compare="isCompare"
 | 
			
		||||
      :labelWidth="labelWidth"
 | 
			
		||||
      :prop="`${prop}${prop ? '.' : ''}${String(index)}`"
 | 
			
		||||
      :size="size"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      @change="changeHandler"
 | 
			
		||||
      @addDiffCount="onAddDiffCount()"
 | 
			
		||||
    ></Container>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@ -54,6 +57,8 @@ import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  lastValues: any;
 | 
			
		||||
  isCompare?: boolean;
 | 
			
		||||
  groupModel: any[];
 | 
			
		||||
  config: GroupListConfig;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
@ -63,7 +68,7 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['swap-item', 'remove-item', 'change']);
 | 
			
		||||
const emit = defineEmits(['swap-item', 'remove-item', 'change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const expand = ref(false);
 | 
			
		||||
@ -122,4 +127,5 @@ const movable = () => {
 | 
			
		||||
  }
 | 
			
		||||
  return movable;
 | 
			
		||||
};
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -23,11 +23,14 @@
 | 
			
		||||
            :key="item[mForm?.keyProp || '__key'] ?? index"
 | 
			
		||||
            :config="item"
 | 
			
		||||
            :model="name ? model[name] : model"
 | 
			
		||||
            :lastValues="name ? lastValues[name] : lastValues"
 | 
			
		||||
            :is-compare="isCompare"
 | 
			
		||||
            :prop="prop"
 | 
			
		||||
            :size="size"
 | 
			
		||||
            :disabled="disabled"
 | 
			
		||||
            :label-width="config.labelWidth || labelWidth"
 | 
			
		||||
            @change="changeHandler"
 | 
			
		||||
            @addDiffCount="onAddDiffCount()"
 | 
			
		||||
          ></Container>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
@ -40,11 +43,14 @@
 | 
			
		||||
          :key="item[mForm?.keyProp || '__key'] ?? index"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :model="name ? model[name] : model"
 | 
			
		||||
          :lastValues="name ? lastValues[name] : lastValues"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :prop="prop"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :label-width="config.labelWidth || labelWidth"
 | 
			
		||||
          @change="changeHandler"
 | 
			
		||||
          @addDiffCount="onAddDiffCount()"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </template>
 | 
			
		||||
    </div>
 | 
			
		||||
@ -64,6 +70,8 @@ import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  lastValues?: any;
 | 
			
		||||
  isCompare?: boolean;
 | 
			
		||||
  config: PanelConfig;
 | 
			
		||||
  name: string;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
@ -72,7 +80,7 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
@ -83,4 +91,5 @@ const items = computed(() => props.config.items);
 | 
			
		||||
const filter = (config: any) => filterFunction(mForm, config, props);
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => emit('change', props.model);
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,13 @@
 | 
			
		||||
      :labelWidth="config.labelWidth || labelWidth"
 | 
			
		||||
      :expandMore="expandMore"
 | 
			
		||||
      :model="name ? model[name] : model"
 | 
			
		||||
      :lastValues="name ? lastValues[name] : lastValues"
 | 
			
		||||
      :is-compare="isCompare"
 | 
			
		||||
      :prop="prop"
 | 
			
		||||
      :size="size"
 | 
			
		||||
      :disabled="disabled"
 | 
			
		||||
      @change="changeHandler"
 | 
			
		||||
      @add-diff-count="onAddDiffCount"
 | 
			
		||||
    />
 | 
			
		||||
  </TMagicRow>
 | 
			
		||||
</template>
 | 
			
		||||
@ -27,6 +30,8 @@ import Col from './Col.vue';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  lastValues?: any;
 | 
			
		||||
  isCompare?: boolean;
 | 
			
		||||
  config: RowConfig;
 | 
			
		||||
  name: string;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
@ -36,9 +41,10 @@ const props = defineProps<{
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
 | 
			
		||||
const changeHandler = () => emit('change', props.name ? props.model[props.name] : props.model);
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,14 @@
 | 
			
		||||
          :key="item[mForm?.keyProp || '__key']"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :model="step.name ? model[step.name] : model"
 | 
			
		||||
          :lastValues="step.name ? lastValues[step.name] : lastValues"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :prop="`${step.name}`"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :label-width="config.labelWidth || labelWidth"
 | 
			
		||||
          @change="changeHandler"
 | 
			
		||||
          @addDiffCount="onAddDiffCount()"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </template>
 | 
			
		||||
    </template>
 | 
			
		||||
@ -41,6 +44,8 @@ import Container from './Container.vue';
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    model: any;
 | 
			
		||||
    lastValues?: any;
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    config: StepConfig;
 | 
			
		||||
    stepActive?: number;
 | 
			
		||||
    labelWidth?: string;
 | 
			
		||||
@ -52,7 +57,7 @@ const props = withDefaults(
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const active = ref(1);
 | 
			
		||||
@ -69,4 +74,5 @@ const stepClick = (index: number) => {
 | 
			
		||||
const changeHandler = () => {
 | 
			
		||||
  emit('change', props.model);
 | 
			
		||||
};
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@
 | 
			
		||||
          style="width: 100%"
 | 
			
		||||
          :row-key="config.rowKey || 'id'"
 | 
			
		||||
          :data="data"
 | 
			
		||||
          :lastData="lastData"
 | 
			
		||||
          :border="config.border"
 | 
			
		||||
          :max-height="config.maxHeight"
 | 
			
		||||
          :default-expand-all="true"
 | 
			
		||||
@ -108,8 +109,11 @@
 | 
			
		||||
                  :rules="column.rules"
 | 
			
		||||
                  :config="makeConfig(column, scope.row)"
 | 
			
		||||
                  :model="scope.row"
 | 
			
		||||
                  :lastValues="lastData[scope.$index]"
 | 
			
		||||
                  :is-compare="isCompare"
 | 
			
		||||
                  :size="size"
 | 
			
		||||
                  @change="$emit('change', model[modelName])"
 | 
			
		||||
                  @addDiffCount="onAddDiffCount()"
 | 
			
		||||
                ></Container>
 | 
			
		||||
              </template>
 | 
			
		||||
            </TMagicTableColumn>
 | 
			
		||||
@ -196,6 +200,8 @@ import Container from './Container.vue';
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    model: any;
 | 
			
		||||
    lastValues?: any;
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    config: TableConfig;
 | 
			
		||||
    name: string;
 | 
			
		||||
    prop?: string;
 | 
			
		||||
@ -213,10 +219,12 @@ const props = withDefaults(
 | 
			
		||||
    sortKey: '',
 | 
			
		||||
    enableToggleMode: true,
 | 
			
		||||
    showIndex: true,
 | 
			
		||||
    lastValues: () => ({}),
 | 
			
		||||
    isCompare: false,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change', 'select']);
 | 
			
		||||
const emit = defineEmits(['change', 'select', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
let timer: any | null = null;
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
@ -241,6 +249,15 @@ const data = computed(() =>
 | 
			
		||||
    : props.model[modelName.value],
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const lastData = computed(() =>
 | 
			
		||||
  props.config.pagination
 | 
			
		||||
    ? props.lastValues[modelName.value].filter(
 | 
			
		||||
        (item: any, index: number) =>
 | 
			
		||||
          index >= pagecontext.value * pagesize.value && index + 1 <= (pagecontext.value + 1) * pagesize.value,
 | 
			
		||||
      )
 | 
			
		||||
    : props.lastValues[modelName.value] || {},
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const sortChange = ({ prop, order }: SortProp) => {
 | 
			
		||||
  if (order === 'ascending') {
 | 
			
		||||
    props.model[modelName.value] = props.model[modelName.value].sort((a: any, b: any) => a[prop] - b[prop]);
 | 
			
		||||
@ -593,6 +610,8 @@ const getProp = (index: number) => {
 | 
			
		||||
  return `${prop.value}${prop.value ? '.' : ''}${index + 1 + pagecontext.value * pagesize.value - 1}`;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const onAddDiffCount = () => emit('addDiffCount');
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
  toggleRowSelection,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -18,25 +18,26 @@
 | 
			
		||||
        :label="filter(tab.title)"
 | 
			
		||||
        :lazy="tab.lazy || false"
 | 
			
		||||
      >
 | 
			
		||||
        <template #label>
 | 
			
		||||
          <span class="custom-tabs-label">
 | 
			
		||||
            {{ filter(tab.title)
 | 
			
		||||
            }}<el-badge :hidden="!diffCount[tabIndex]" :value="diffCount[tabIndex]" class="diff-count-badge"></el-badge>
 | 
			
		||||
          </span>
 | 
			
		||||
        </template>
 | 
			
		||||
        <Container
 | 
			
		||||
          v-for="item in tabItems(tab)"
 | 
			
		||||
          :key="item[mForm?.keyProp || '__key']"
 | 
			
		||||
          :config="item"
 | 
			
		||||
          :disabled="disabled"
 | 
			
		||||
          :model="
 | 
			
		||||
            config.dynamic
 | 
			
		||||
              ? (name ? model[name] : model)[tabIndex]
 | 
			
		||||
              : tab.name
 | 
			
		||||
              ? (name ? model[name] : model)[tab.name]
 | 
			
		||||
              : name
 | 
			
		||||
              ? model[name]
 | 
			
		||||
              : model
 | 
			
		||||
          "
 | 
			
		||||
          :model="getValues(model, tabIndex, tab)"
 | 
			
		||||
          :last-values="getValues(lastValues, tabIndex, tab)"
 | 
			
		||||
          :is-compare="isCompare"
 | 
			
		||||
          :prop="config.dynamic ? `${prop}${prop ? '.' : ''}${String(tabIndex)}` : prop"
 | 
			
		||||
          :size="size"
 | 
			
		||||
          :label-width="tab.labelWidth || labelWidth"
 | 
			
		||||
          :expand-more="expandMore"
 | 
			
		||||
          @change="changeHandler"
 | 
			
		||||
          @addDiffCount="onAddDiffCount(tabIndex)"
 | 
			
		||||
        ></Container>
 | 
			
		||||
      </component>
 | 
			
		||||
    </template>
 | 
			
		||||
@ -54,6 +55,10 @@ import { display as displayFunc, filterFunction } from '../utils/form';
 | 
			
		||||
 | 
			
		||||
import Container from './Container.vue';
 | 
			
		||||
 | 
			
		||||
type DiffCount = {
 | 
			
		||||
  [tabIndex: number]: number;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uiComponent = getConfig('components').tabPane;
 | 
			
		||||
 | 
			
		||||
const getActive = (mForm: FormState | undefined, props: any, activeTabName: string) => {
 | 
			
		||||
@ -83,21 +88,30 @@ const tabClick = (mForm: FormState | undefined, tab: any, props: any) => {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
  model: any;
 | 
			
		||||
  config: TabConfig;
 | 
			
		||||
  name: string;
 | 
			
		||||
  size?: string;
 | 
			
		||||
  labelWidth?: string;
 | 
			
		||||
  prop?: string;
 | 
			
		||||
  expandMore?: boolean;
 | 
			
		||||
  disabled?: boolean;
 | 
			
		||||
}>();
 | 
			
		||||
const props = withDefaults(
 | 
			
		||||
  defineProps<{
 | 
			
		||||
    model: any;
 | 
			
		||||
    lastValues?: any;
 | 
			
		||||
    isCompare?: boolean;
 | 
			
		||||
    config: TabConfig;
 | 
			
		||||
    name: string;
 | 
			
		||||
    size?: string;
 | 
			
		||||
    labelWidth?: string;
 | 
			
		||||
    prop?: string;
 | 
			
		||||
    expandMore?: boolean;
 | 
			
		||||
    disabled?: boolean;
 | 
			
		||||
  }>(),
 | 
			
		||||
  {
 | 
			
		||||
    lastValues: () => ({}),
 | 
			
		||||
    isCompare: false,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits(['change']);
 | 
			
		||||
const emit = defineEmits(['change', 'addDiffCount']);
 | 
			
		||||
 | 
			
		||||
const mForm = inject<FormState | undefined>('mForm');
 | 
			
		||||
const activeTabName = ref(getActive(mForm, props, ''));
 | 
			
		||||
const diffCount = ref<DiffCount>({});
 | 
			
		||||
 | 
			
		||||
const tabs = computed(() => {
 | 
			
		||||
  if (props.config.dynamic) {
 | 
			
		||||
@ -170,4 +184,27 @@ const changeHandler = () => {
 | 
			
		||||
    props.config.onChange(mForm, { model: props.model, prop: props.prop, config: props.config });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getValues = (model: any, tabIndex: number, tab: any) => {
 | 
			
		||||
  const tabName = props.config.dynamic ? (model[props?.name] || model)[tabIndex] : tab.name;
 | 
			
		||||
  let propName = props.name;
 | 
			
		||||
  if (tabName) {
 | 
			
		||||
    propName = (model[props?.name] || model)[tab.name];
 | 
			
		||||
  }
 | 
			
		||||
  if (propName) {
 | 
			
		||||
    return model[props.name];
 | 
			
		||||
  }
 | 
			
		||||
  return model;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 在tabs组件中收集事件触发次数,即该tab下的差异数
 | 
			
		||||
const onAddDiffCount = (tabIndex: number) => {
 | 
			
		||||
  if (!diffCount.value[tabIndex]) {
 | 
			
		||||
    diffCount.value[tabIndex] = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    diffCount.value[tabIndex] += 1;
 | 
			
		||||
  }
 | 
			
		||||
  // 继续抛出给更高层级的组件
 | 
			
		||||
  emit('addDiffCount');
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,8 @@ export type FormState = {
 | 
			
		||||
  config: FormConfig;
 | 
			
		||||
  popperClass?: string;
 | 
			
		||||
  initValues: FormValue;
 | 
			
		||||
  lastValues: FormValue;
 | 
			
		||||
  isCompare: boolean;
 | 
			
		||||
  values: FormValue;
 | 
			
		||||
  $emit: (event: string, ...args: any[]) => void;
 | 
			
		||||
  keyProp?: string;
 | 
			
		||||
 | 
			
		||||
@ -7,3 +7,4 @@
 | 
			
		||||
@use "./panel.scss";
 | 
			
		||||
@use "./table.scss";
 | 
			
		||||
@use "./select.scss";
 | 
			
		||||
@use "./tabs.scss";
 | 
			
		||||
 | 
			
		||||
@ -23,3 +23,7 @@
 | 
			
		||||
.magic-form-tab {
 | 
			
		||||
  margin-bottom: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.diff-count-badge {
 | 
			
		||||
  top: -10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,21 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div style="width: 100%">
 | 
			
		||||
  <div style="width: 100%; overflow-y: auto">
 | 
			
		||||
    <nav-menu :data="menu"></nav-menu>
 | 
			
		||||
    <div class="diff-form">
 | 
			
		||||
      <div>开启表单对比功能</div>
 | 
			
		||||
      <m-form
 | 
			
		||||
        ref="form"
 | 
			
		||||
        :config="diffFormConfig"
 | 
			
		||||
        :is-compare="true"
 | 
			
		||||
        :init-values="currentVersion"
 | 
			
		||||
        :last-values="lastVersion"
 | 
			
		||||
        size="small"
 | 
			
		||||
        height="100%"
 | 
			
		||||
      ></m-form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="title">表单字段展示</div>
 | 
			
		||||
    <div class="form-content">
 | 
			
		||||
      <m-form ref="form" :config="config" :init-values="initValue" size="small" height="100%"></m-form>
 | 
			
		||||
 | 
			
		||||
      <magic-code-editor class="code-editor-content" :init-values="config" @save="change"></magic-code-editor>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
@ -30,6 +42,58 @@ const resultVisible = ref(false);
 | 
			
		||||
const result = ref('');
 | 
			
		||||
const form = ref<InstanceType<typeof MForm>>();
 | 
			
		||||
 | 
			
		||||
const diffFormConfig = ref([
 | 
			
		||||
  {
 | 
			
		||||
    type: 'tab',
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        title: 'tab1',
 | 
			
		||||
        labelWidth: '80px',
 | 
			
		||||
        items: [
 | 
			
		||||
          {
 | 
			
		||||
            name: 'text1',
 | 
			
		||||
            text: '文本字段1',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'text2',
 | 
			
		||||
            text: '文本字段2',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'number',
 | 
			
		||||
            text: '计数器',
 | 
			
		||||
            name: 'number',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        title: 'tab2',
 | 
			
		||||
        labelWidth: '80px',
 | 
			
		||||
        items: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'colorPicker',
 | 
			
		||||
            text: '取色器',
 | 
			
		||||
            name: 'colorPicker',
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
const currentVersion = ref({
 | 
			
		||||
  text1: '当前版本的文本内容',
 | 
			
		||||
  text2: '你好',
 | 
			
		||||
  number: 10,
 | 
			
		||||
  colorPicker: '#ffffff',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const lastVersion = ref({
 | 
			
		||||
  text1: '上一版本的文本内容',
 | 
			
		||||
  text2: '你好',
 | 
			
		||||
  number: 12,
 | 
			
		||||
  colorPicker: '#000000',
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const config = ref([
 | 
			
		||||
  {
 | 
			
		||||
    text: '文本',
 | 
			
		||||
@ -358,9 +422,16 @@ function change(value: string) {
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.diff-form {
 | 
			
		||||
  width: 500px;
 | 
			
		||||
  margin: 20px 0 0 50px;
 | 
			
		||||
}
 | 
			
		||||
.title {
 | 
			
		||||
  margin: 20px 0 0 50px;
 | 
			
		||||
}
 | 
			
		||||
.form-content {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  height: calc(100% - 75px);
 | 
			
		||||
  height: 800px;
 | 
			
		||||
 | 
			
		||||
  .code-editor-content,
 | 
			
		||||
  .m-form {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user