mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-09 20:57:17 +08:00
refactor: 优化 GiForm、GiEditTable(同步 GiDemo 更新)
This commit is contained in:
@@ -45,15 +45,18 @@ import type { TableColumnData, TableData } from '@arco-design/web-vue'
|
||||
import type { ColumnItem, Disabled } from './type'
|
||||
|
||||
defineOptions({ name: 'GiEditTable', inheritAttrs: false })
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
cellDisabled: false,
|
||||
})
|
||||
|
||||
/** 事件定义 */
|
||||
const emit = defineEmits<{
|
||||
(e: 'tr-dblclick', value: { record: any, rowIndex: number }): void
|
||||
(e: 'td-dblclick', value: { record: any, rowIndex: number, column: TableColumnData }): void
|
||||
}>()
|
||||
|
||||
/** 插槽定义 */
|
||||
defineSlots<{
|
||||
[propsName: string]: (props: { record: T, rowIndex: number, column: ColumnItem }) => void
|
||||
}>()
|
||||
@@ -66,36 +69,61 @@ interface Props {
|
||||
|
||||
const attrs = useAttrs()
|
||||
|
||||
/** 表单数据 */
|
||||
const form = computed(() => ({ tableData: props.data }))
|
||||
|
||||
/** 表单实例 */
|
||||
const formRef = useTemplateRef('formRef')
|
||||
|
||||
/** 获取表头必填星号*样式 */
|
||||
const headerCellClass = (col: ColumnItem) => {
|
||||
return col.required ? 'gi_column_require' : ''
|
||||
}
|
||||
|
||||
const getComponentBindProps = (col: ColumnItem) => {
|
||||
// 组件默认配置映射表
|
||||
const ConfigMap = new Map<ColumnItem['type'], Partial<Omit<ColumnItem['props'], 'placeholder'> & { placeholder?: string | string[] }>>([
|
||||
['input', { allowClear: true, placeholder: `请输入${col.title}`, maxLength: 50 }],
|
||||
['input-number', { placeholder: `请输入${col.title}` }],
|
||||
['textarea', { allowClear: false, placeholder: `请填写${col.title}`, maxLength: 200 }],
|
||||
['input-tag', { allowClear: true, placeholder: `请输入${col.title}` }],
|
||||
['mention', { allowClear: true, placeholder: `请输入${col.title}` }],
|
||||
['select', { allowClear: true, placeholder: `请选择${col.title}` }],
|
||||
['tree-select', { allowClear: true, placeholder: `请选择${col.title}` }],
|
||||
['cascader', { allowClear: true, placeholder: `请选择${col.title}` }],
|
||||
['radio-group', {}],
|
||||
['checkbox-group', {}],
|
||||
['date-picker', { allowClear: true, placeholder: '请选择日期' }],
|
||||
['time-picker', { allowClear: true, placeholder: '请选择时间' }],
|
||||
/** 静态配置 */
|
||||
const STATIC_PROPS = new Map<ColumnItem['type'], Partial<ColumnItem['props']>>([
|
||||
['input', { allowClear: true, maxLength: 20 }],
|
||||
['textarea', { allowClear: false, maxLength: 200 }],
|
||||
['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 defaultProps = ConfigMap.get(col.type) || {}
|
||||
// 合并默认配置和自定义配置
|
||||
return { ...defaultProps, ...col.props }
|
||||
|
||||
/** 获取组件默认占位 */
|
||||
const getPlaceholder = (item: ColumnItem) => {
|
||||
if (!item.type) return undefined
|
||||
if (['input', 'input-tag', 'mention'].includes(item.type)) {
|
||||
return `请输入${item.title}`
|
||||
}
|
||||
if (['textarea'].includes(item.type)) {
|
||||
return `请填写${item.title}`
|
||||
}
|
||||
if (['select', 'tree-select', 'cascader'].includes(item.type)) {
|
||||
return `请选择${item.title}`
|
||||
}
|
||||
if (['date-picker'].includes(item.type)) {
|
||||
return '请选择日期'
|
||||
}
|
||||
if (['time-picker'].includes(item.type)) {
|
||||
return '请选择时间'
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
/** 获取组件默认配置 */
|
||||
const getComponentBindProps = (col: ColumnItem) => {
|
||||
return {
|
||||
...STATIC_PROPS.get(col.type) || {},
|
||||
placeholder: getPlaceholder(col),
|
||||
...col.props,
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取组件默认规则 */
|
||||
const getRuleMessage = (col: ColumnItem) => {
|
||||
if (['input', 'input-number', 'input-tag', 'mention'].includes(col.type ?? '')) {
|
||||
return `请输入${col.title}`
|
||||
@@ -106,12 +134,14 @@ const getRuleMessage = (col: ColumnItem) => {
|
||||
return `请选择${col.title}`
|
||||
}
|
||||
|
||||
/** 判断是否禁用 */
|
||||
const isDisabled: Props['cellDisabled'] = (p) => {
|
||||
if (typeof props?.cellDisabled === 'boolean') return props.cellDisabled
|
||||
if (typeof props?.cellDisabled === 'function') return props.cellDisabled(p)
|
||||
return false
|
||||
}
|
||||
|
||||
/** 暴露表单实例 */
|
||||
defineExpose({ formRef })
|
||||
</script>
|
||||
|
||||
|
@@ -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 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 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 defaultProps = ConfigMap.get(item.type) || {}
|
||||
// 合并默认配置和自定义配置
|
||||
return { ...defaultProps, ...item.props }
|
||||
|
||||
/** 获取组件默认占位 */
|
||||
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) => {
|
||||
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 }))
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
<!-- 列拖拽排序区域 -->
|
||||
<div class="gi-table__draggable">
|
||||
<VueDraggable v-model="localColumns" @end="handleDragEnd">
|
||||
<VueDraggable v-model="localColumns" :animation="150" @end="handleDragEnd">
|
||||
<div
|
||||
v-for="item in localColumns"
|
||||
:key="item.key"
|
||||
|
2
src/types/components.d.ts
vendored
2
src/types/components.d.ts
vendored
@@ -11,6 +11,7 @@ declare module 'vue' {
|
||||
Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default']
|
||||
CellCopy: typeof import('./../components/CellCopy/index.vue')['default']
|
||||
Chart: typeof import('./../components/Chart/index.vue')['default']
|
||||
ColumnSetting: typeof import('./../components/GiTable/src/components/ColumnSetting.vue')['default']
|
||||
CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default']
|
||||
CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default']
|
||||
DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default']
|
||||
@@ -58,7 +59,6 @@ declare module 'vue' {
|
||||
SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default']
|
||||
SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default']
|
||||
TextCopy: typeof import('./../components/TextCopy/index.vue')['default']
|
||||
ToggleDark: typeof import('./../components/ToggleDark/index.vue')['default']
|
||||
UserSelect: typeof import('./../components/UserSelect/index.vue')['default']
|
||||
Verify: typeof import('./../components/Verify/index.vue')['default']
|
||||
VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default']
|
||||
|
@@ -72,7 +72,7 @@ const {
|
||||
const columns: TableInstance['columns'] = [
|
||||
{
|
||||
title: '序号',
|
||||
width: 66,
|
||||
minWidth: 66,
|
||||
align: 'center',
|
||||
render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize),
|
||||
},
|
||||
|
@@ -83,7 +83,7 @@ const {
|
||||
const columns: TableInstance['columns'] = [
|
||||
{
|
||||
title: '序号',
|
||||
width: 66,
|
||||
minWidth: 66,
|
||||
align: 'center',
|
||||
render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize),
|
||||
},
|
||||
|
@@ -40,7 +40,7 @@
|
||||
<GiIconSelector v-model="form.icon" />
|
||||
</a-form-item>
|
||||
<a-form-item v-else label="权限标识" field="permission">
|
||||
<a-input v-model.trim="form.permission" placeholder="system:user:add" allow-clear />
|
||||
<a-input v-model.trim="form.permission" placeholder="system:user:add" :max-length="100" show-word-limit allow-clear />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
@@ -80,7 +80,7 @@
|
||||
</a-col>
|
||||
<a-col v-bind="colProps">
|
||||
<a-form-item v-if="form.type === 2" label="权限标识" field="permission">
|
||||
<a-input v-model.trim="form.permission" placeholder="system:user:add" allow-clear />
|
||||
<a-input v-model.trim="form.permission" placeholder="system:user:add" :max-length="100" show-word-limit allow-clear />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
Reference in New Issue
Block a user