refactor: 优化 GiForm、GiEditTable(同步 GiDemo 更新)

This commit is contained in:
2025-03-21 21:14:39 +08:00
parent 1d77d8c51a
commit 436cc6bdfc
7 changed files with 113 additions and 51 deletions

View File

@@ -29,7 +29,7 @@
<component
:is="`a-${item.type}`" v-else v-bind="getComponentBindProps(item)"
:model-value="modelValue[item.field as keyof typeof modelValue]"
@update:model-value="valueChange($event, item.field)"
@update:model-value="updateValue($event, item.field)"
>
<template v-for="(slotValue, slotKey) in item?.slots" :key="slotKey" #[slotKey]="scope">
<template v-if="typeof slotValue === 'string'">{{ slotValue }}</template>
@@ -50,8 +50,9 @@
</a-grid-item>
</template>
<a-grid-item
v-if="props.search" v-bind="defaultGridItemProps" :span="defaultGridItemProps?.span"
:suffix="props.search && props.suffix"
v-if="props.search" :key="!props.suffix ? String(collapsed) : undefined"
v-bind="defaultGridItemProps" :span="defaultGridItemProps?.span"
:suffix="props.search && (props.suffix || (!props.suffix && collapsed))"
>
<a-space wrap>
<slot name="suffix">
@@ -135,35 +136,66 @@ const defaultGridItemProps = computed(() => {
})
const formRef = useTemplateRef('formRef')
/** 是否折叠 */
const collapsed = ref(props.defaultCollapsed)
/** 数据字典 */
const dicData: Record<string, any> = reactive({})
// 组件的默认props配置
/** 静态配置 */
const STATIC_PROPS = new Map<ColumnItem['type'], Partial<ColumnItem['props']>>([
['input', { allowClear: true, maxLength: 255, showWordLimit: !props.search }],
['input-password', { allowClear: true, showWordLimit: !props.search }],
['textarea', { allowClear: false, maxLength: 200, showWordLimit: !props.search, autoSize: { minRows: 3, maxRows: 5 } }],
['input-tag', { allowClear: true }],
['mention', { allowClear: true }],
['select', { allowClear: true }],
['tree-select', { allowClear: true }],
['cascader', { allowClear: true }],
['date-picker', { allowClear: true }],
['time-picker', { allowClear: true }],
])
/** 获取组件默认占位 */
const getPlaceholder = (item: ColumnItem) => {
if (!item.type) return undefined
if (['input', 'input-number', 'input-password', 'textarea', 'input-tag', 'mention'].includes(item.type)) {
return `请输入${item.label}`
}
if (['select', 'tree-select', 'cascader'].includes(item.type)) {
return `请选择${item.label}`
}
if (['date-picker'].includes(item.type)) {
return '请选择日期'
}
if (['time-picker'].includes(item.type)) {
return '请选择时间'
}
return undefined
}
/** 获取选项数据 */
const getOptions = (item: ColumnItem): any[] | undefined => {
if (!item.type) return undefined
/** 需要选项数据的组件类型 */
const arr = ['select', 'tree-select', 'cascader', 'radio-group', 'checkbox-group']
if (arr.includes(item.type)) {
return dicData[item.field] || []
}
return undefined
}
/** 获取组件绑定属性 */
const getComponentBindProps = (item: ColumnItem) => {
// 组件默认配置映射表
const ConfigMap = new Map<ColumnItem['type'], Partial<ColumnItem['props'] & { placeholder: string }>>([
['input', { allowClear: true, placeholder: `请输入${item.label}`, maxLength: 255, showWordLimit: !props.search }],
['input-password', { placeholder: `请输入${item.label}`, showWordLimit: !props.search }],
['input-number', { placeholder: `请输入${item.label}` }],
['textarea', { allowClear: false, placeholder: `请输入${item.label}`, maxLength: 200, showWordLimit: !props.search, autoSize: { minRows: 3, maxRows: 5 } }],
['input-tag', { allowClear: true, placeholder: `请输入${item.label}` }],
['mention', { allowClear: true, placeholder: `请输入${item.label}` }],
['select', { allowClear: true, placeholder: `请选择${item.label}`, options: dicData[item.field] || [] }],
['tree-select', { allowClear: true, placeholder: `请选择${item.label}` }],
['cascader', { allowClear: true, placeholder: `请选择${item.label}`, options: dicData[item.field] || [] }],
['radio-group', { options: dicData[item.field] || [] }],
['checkbox-group', { options: dicData[item.field] || [] }],
['date-picker', { allowClear: true, placeholder: '请选择日期' }],
['time-picker', { allowClear: true, placeholder: '请选择时间' }],
])
// 获取默认配置
const defaultProps = ConfigMap.get(item.type) || {}
// 合并默认配置和自定义配置
return { ...defaultProps, ...item.props }
return {
...STATIC_PROPS.get(item.type) || {},
placeholder: getPlaceholder(item),
options: getOptions(item),
...item.props,
}
}
/** 表单数据更新 */
const valueChange = (value: any, field: string) => {
const updateValue = (value: any, field: string) => {
emit('update:modelValue', Object.assign(props.modelValue, { [field]: value }))
}