roymondchen cbc4b25072 feat(editor): 字段对比模式逐项展示差异并补充历史记录面板文档
- CodeSelect/CodeSelectCol/EventSelect/DataSource 等复合字段在对比模式下
  按索引对齐前后值,逐项展示新增/删除/修改高亮,并隐藏写操作按钮
- form 容器/列表/表格支持对比模式只读展示
- 新增「历史记录面板」指南文档,完善表单对比文档及 menu props 说明
- 补充相关单元测试

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 15:51:47 +08:00

93 lines
2.1 KiB
Vue

<template>
<MForm
ref="form"
:config="codeParamsConfig"
:init-values="model"
:last-values="lastValues"
:is-compare="isCompare"
:disabled="disabled"
:size="size"
:watch-props="false"
@change="onParamsChangeHandler"
></MForm>
</template>
<script lang="ts" setup>
import { computed, useTemplateRef } from 'vue';
import { type ContainerChangeEventData, type FormItemConfig, type FormValue, MForm } from '@tmagic/form';
import type { CodeParamStatement } from '@editor/type';
import { error } from '@editor/utils';
defineOptions({
name: 'MEditorCodeParams',
});
const props = defineProps<{
model: any;
/** 对比模式下的历史值,透传给内部 MForm 用于逐项展示参数差异 */
lastValues?: any;
/** 是否开启对比模式 */
isCompare?: boolean;
size?: 'small' | 'default' | 'large';
disabled?: boolean;
name: string;
paramsConfig: CodeParamStatement[];
}>();
const emit = defineEmits(['change']);
const formRef = useTemplateRef<InstanceType<typeof MForm>>('form');
const getFormConfig = (items: FormItemConfig[] = []) => [
{
type: 'fieldset',
items,
legend: '参数',
labelWidth: '120px',
name: props.name,
},
];
const codeParamsConfig = computed(() =>
getFormConfig(
props.paramsConfig.map(({ name, text, extra, ...config }) => {
let { type } = config;
if (typeof type === 'function') {
type = type(undefined, {
model: props.model[props.name],
});
}
if (type && ['data-source-field-select', 'vs-code'].includes(type)) {
return {
...config,
name,
text,
extra,
};
}
return {
type: 'data-source-field-select' as const,
name,
text,
extra,
fieldConfig: config,
};
}) as FormItemConfig[],
),
);
/**
* 参数值修改更新
*/
const onParamsChangeHandler = async (v: FormValue, eventData: ContainerChangeEventData) => {
try {
const value = await formRef.value?.submitForm(true);
emit('change', value, eventData);
} catch (e) {
error(e);
}
};
</script>