@aspire-ui/element-component-pro 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/ProForm/ApiSelect.vue.d.ts +9 -1
- package/dist/ProForm/ProForm.vue.d.ts +8 -0
- package/dist/ProForm/ProFormItem.vue.d.ts +4 -0
- package/dist/ProTable/ProTable.vue.d.ts +7 -1
- package/dist/ProTable/types/index.d.ts +1 -0
- package/dist/ProTableForm/ProTableForm.vue.d.ts +164 -0
- package/dist/ProTableForm/index.d.ts +5 -0
- package/dist/ProTableForm/types.d.ts +69 -0
- package/dist/element-component-pro.es.js +1305 -980
- package/dist/element-component-pro.es.js.map +1 -1
- package/dist/element-component-pro.umd.js +2 -2
- package/dist/element-component-pro.umd.js.map +1 -1
- package/dist/index.d.ts +796 -243
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +20 -1
- package/dist/useComponentSetting.d.ts +9 -4
- package/package.json +1 -1
- package/src/ProDescriptions/ProDescriptions.vue +2 -2
- package/src/ProForm/ApiSelect.vue +17 -5
- package/src/ProForm/ProForm.vue +47 -4
- package/src/ProForm/ProFormItem.vue +19 -1
- package/src/ProTable/ProTable.vue +36 -5
- package/src/ProTable/types/index.ts +1 -0
- package/src/ProTableForm/ProTableForm.vue +555 -0
- package/src/ProTableForm/index.ts +9 -0
- package/src/ProTableForm/types.ts +72 -0
- package/src/index.ts +10 -0
- package/src/types/index.ts +15 -0
- package/src/useComponentSetting.ts +63 -8
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.ecp-pro-table[data-v-
|
|
1
|
+
.ecp-pro-table[data-v-f3d27813]{padding:16px;background:#fff;width:100%;box-sizing:border-box}.ecp-pro-table[data-v-f3d27813] .el-table{width:100%!important}.ecp-pro-table__header[data-v-f3d27813]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.ecp-pro-table__title-wrapper[data-v-f3d27813]{display:flex;align-items:center;gap:4px}.ecp-pro-table__title[data-v-f3d27813]{font-size:16px;font-weight:600}.ecp-pro-table__help[data-v-f3d27813]{color:#909399;cursor:help}.ecp-pro-table__toolbar[data-v-f3d27813]{display:flex;align-items:center;gap:8px}.ecp-pro-table__body[data-v-f3d27813]{width:100%}.ecp-pro-table__pagination[data-v-f3d27813]{margin-top:16px;display:flex;justify-content:flex-end}.ecp-pro-table__col-help[data-v-f3d27813]{margin-left:4px;color:#909399;cursor:help}.ecp-table-action[data-v-45a58e7c],.ecp-table-action__item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-table-action__icon[data-v-45a58e7c]{margin-right:4px}.ecp-table-action__more[data-v-45a58e7c]{display:inline-flex;align-items:center}.ecp-table-action__dropdown-item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-tree-select[data-v-f30bba11]{position:relative;width:100%}.ecp-tree-select__filter-inner[data-v-f30bba11]{margin-bottom:8px}.ecp-tree-select__dropdown[data-v-f30bba11]{position:absolute;top:100%;left:0;right:0;max-height:280px;overflow:auto;background:#fff;border:1px solid #dcdfe6;border-radius:4px;margin-top:4px;z-index:1000;padding:8px}.ecp-tree-select__loading[data-v-f30bba11]{padding:24px;text-align:center;color:#909399;font-size:14px}.ecp-pro-form-item__colon[data-v-48d7960b]{margin-right:2px}.ecp-pro-form-item__help-icon[data-v-48d7960b]{margin-left:4px;color:#909399;cursor:help;font-size:14px}.ecp-pro-form-item__help-icon[data-v-48d7960b]:hover{color:#409eff}.ecp-pro-form-item__help-item[data-v-48d7960b]{margin-bottom:4px}.ecp-pro-form-item__help-item[data-v-48d7960b]:last-child{margin-bottom:0}.ecp-form-actions[data-v-489c88d2]{text-align:right}.ecp-form-actions__advance[data-v-489c88d2]{margin-right:8px}.el-icon-d-arrow-left.up[data-v-489c88d2]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-489c88d2]{transform:rotate(-90deg)}.ecp-pro-form[data-v-7ee469dc]{padding:16px;position:relative}.ecp-pro-form__advance[data-v-7ee469dc]{margin-bottom:16px}.ecp-pro-form_col[data-v-7ee469dc]{position:relative;float:right}.el-icon-d-arrow-left.up[data-v-7ee469dc]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-7ee469dc]{transform:rotate(-90deg)}.ecp-form-actions__advance[data-v-7ee469dc]{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%)}.ecp-pro-descriptions[data-v-656036f6]{width:100%;box-sizing:border-box}.ecp-pro-descriptions__header[data-v-656036f6]{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;gap:12px}.ecp-pro-descriptions__title-wrap[data-v-656036f6]{display:flex;align-items:center;gap:6px}.ecp-pro-descriptions__title[data-v-656036f6]{font-size:16px;font-weight:600;color:#303133}.ecp-pro-descriptions__help[data-v-656036f6],.ecp-pro-descriptions__toggle[data-v-656036f6]{color:#909399}.ecp-pro-descriptions__toggle .el-icon-arrow-down[data-v-656036f6]{margin-left:4px;transition:transform .2s ease}.ecp-pro-descriptions__toggle .el-icon-arrow-down.is-expanded[data-v-656036f6]{transform:rotate(180deg)}.ecp-pro-descriptions__body[data-v-656036f6]{display:grid;border-top:1px solid #ebeef5;border-left:1px solid #ebeef5;overflow:hidden}.ecp-pro-descriptions__body.is-collapsed[data-v-656036f6]{overflow:hidden}.ecp-pro-descriptions__body[data-v-656036f6]:not(.is-bordered){border-top:0;border-left:0;gap:12px 16px}.ecp-pro-descriptions__item[data-v-656036f6]{display:flex;min-width:0;border-right:1px solid #ebeef5;border-bottom:1px solid #ebeef5}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__item[data-v-656036f6]{border-right:0;border-bottom:0}.ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__content[data-v-656036f6]{min-width:0;box-sizing:border-box;word-break:break-word}.ecp-pro-descriptions__label[data-v-656036f6]{flex:0 0 120px;padding:12px 16px;color:#606266;background:#fafafa}.ecp-pro-descriptions__content[data-v-656036f6]{flex:1;padding:12px 16px;color:#303133;background:#fff}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto;padding:0;margin-right:8px;background:transparent;font-weight:500}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__content[data-v-656036f6]{padding:0;background:transparent}.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__content[data-v-656036f6]{padding-top:8px;padding-bottom:8px;font-size:13px}@media (max-width: 767px){.ecp-pro-descriptions__item[data-v-656036f6]{flex-direction:column}.ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto}}.ecp-pro-table-form__form[data-v-44aa7592] .el-form-item{margin-bottom:0}.ecp-pro-table-form__cell-item[data-v-44aa7592]{width:100%}.ecp-pro-table-form__cell-item[data-v-44aa7592] .el-form-item__content{margin-left:0!important;line-height:normal}.ecp-pro-table-form__fixed-label[data-v-44aa7592]{color:#303133;font-size:14px}.ecp-pro-table-form__req[data-v-44aa7592]{color:#f56c6c;margin-right:2px}.ecp-pro-table-form__th-text[data-v-44aa7592]{font-weight:500;color:#606266}.ecp-pro-table-form__action-title[data-v-44aa7592]{margin-right:8px;font-size:13px;color:#606266}.ecp-pro-table-form__add-btn[data-v-44aa7592]{padding:0;font-size:14px}.ecp-pro-table-form__del-btn[data-v-44aa7592]{padding:0;color:#909399}.ecp-pro-table-form__del-btn[data-v-44aa7592]:not(:disabled){color:#409eff}.ecp-pro-table-form .ecp-pro-table-form__header-cell{background:#f5f7fa!important}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VNode } from 'vue';
|
|
1
|
+
import { VNode, ComponentPublicInstance } from 'vue';
|
|
2
2
|
|
|
3
3
|
/** 栅格配置 */
|
|
4
4
|
export interface ColEx {
|
|
@@ -28,6 +28,15 @@ export interface ScrollToFieldOptions {
|
|
|
28
28
|
/** 行内对齐 */
|
|
29
29
|
inline?: ScrollLogicalPosition;
|
|
30
30
|
}
|
|
31
|
+
/** ApiSelect 暴露的实例类型 */
|
|
32
|
+
export interface ApiSelectInstance {
|
|
33
|
+
options: Array<{
|
|
34
|
+
label: string;
|
|
35
|
+
value: unknown;
|
|
36
|
+
}>;
|
|
37
|
+
loading: boolean;
|
|
38
|
+
fetchOptions: () => Promise<void>;
|
|
39
|
+
}
|
|
31
40
|
/** 表单操作类型(参考 Vben Admin FormActionType) */
|
|
32
41
|
export interface FormActionType {
|
|
33
42
|
getFieldsValue: () => Record<string, unknown>;
|
|
@@ -42,6 +51,15 @@ export interface FormActionType {
|
|
|
42
51
|
appendSchemaByField: (schema: ProFormSchema, prefixField?: string, first?: boolean) => Promise<void>;
|
|
43
52
|
removeSchemaByField: (field: string | string[]) => Promise<void>;
|
|
44
53
|
setProps: (props: Partial<ProFormProps>) => Promise<void>;
|
|
54
|
+
/** 获取指定字段的组件实例 */
|
|
55
|
+
getComponentInstance: (field: string) => ComponentPublicInstance | null;
|
|
56
|
+
/** 获取 api-select 字段的 options */
|
|
57
|
+
getFieldOptions: (field: string) => Array<{
|
|
58
|
+
label: string;
|
|
59
|
+
value: unknown;
|
|
60
|
+
}>;
|
|
61
|
+
/** 获取 api-select 字段的加载状态 */
|
|
62
|
+
isFieldLoading: (field: string) => boolean;
|
|
45
63
|
}
|
|
46
64
|
/** 时间字段映射 [表单字段, [开始字段, 结束字段], 格式?] */
|
|
47
65
|
export type FieldMapToTime = [string, [string, string], string?];
|
|
@@ -188,6 +206,7 @@ export interface DescriptionSchema {
|
|
|
188
206
|
}
|
|
189
207
|
/** Description Props */
|
|
190
208
|
export interface DescriptionProps {
|
|
209
|
+
[key: string]: unknown;
|
|
191
210
|
title?: string;
|
|
192
211
|
helpMessage?: string | string[];
|
|
193
212
|
size?: 'medium' | 'small';
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
export interface UseComponentSettingReturn {
|
|
2
2
|
/** 获取组件默认配置;不传参时返回全部组件的配置 */
|
|
3
|
-
getSetting:
|
|
4
|
-
/**
|
|
3
|
+
getSetting: <T extends Record<string, unknown> = Record<string, unknown>>(componentName?: string) => T;
|
|
4
|
+
/** 设置组件默认配置(与已有配置深度合并) */
|
|
5
5
|
setSetting: (componentName: string, config: Record<string, unknown>) => void;
|
|
6
|
+
/** 合并组件配置:全局配置与组件 props 合并,返回合并后的结果 */
|
|
7
|
+
mergeSettings: <T extends Record<string, unknown> = Record<string, unknown>>(componentName: string, props: Record<string, unknown>) => T;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* 组件默认配置:供所有组件统一获取/设置默认配置
|
|
9
|
-
* - getSetting
|
|
10
|
-
* - setSetting
|
|
11
|
+
* - getSetting:获取组件默认配置
|
|
12
|
+
* - setSetting:设置组件默认配置(深度合并),可在应用入口或按需调用
|
|
13
|
+
* - mergeSettings:合并全局配置与组件 props,props 优先级更高
|
|
14
|
+
*
|
|
15
|
+
* 合并优先级:组件默认值 < 全局配置 < 组件 props
|
|
11
16
|
*/
|
|
12
17
|
export declare function useComponentSetting(): UseComponentSettingReturn;
|
package/package.json
CHANGED
|
@@ -181,8 +181,8 @@ const normalizeTooltip = (schema: DescriptionSchema, value: unknown, record: Rec
|
|
|
181
181
|
return normalizeTooltipConfig(resolved, value)
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
const {
|
|
185
|
-
const effectiveProps = computed(() => (
|
|
184
|
+
const { mergeSettings } = useComponentSetting()
|
|
185
|
+
const effectiveProps = computed(() => mergeSettings<DescriptionProps>('ProDescriptions', { ...props, ...innerProps.value }))
|
|
186
186
|
|
|
187
187
|
const breakpoints = { xxl: 1920, xl: 1200, lg: 992, md: 768, sm: 576 }
|
|
188
188
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-select
|
|
3
|
-
|
|
4
|
-
@visible-change="onVisibleChange">
|
|
2
|
+
<el-select v-bind="{ ...$attrs, value: value, placeholder, disabled, loading, clearable, filterable, multiple }"
|
|
3
|
+
@input="$emit('input', $event)" @change="$emit('change', $event)" @visible-change="onVisibleChange">
|
|
5
4
|
<el-option v-for="opt in options" :key="String(opt.value)" :label="opt.label" :value="opt.value" />
|
|
6
5
|
</el-select>
|
|
7
6
|
</template>
|
|
@@ -31,13 +30,19 @@ const props = withDefaults(
|
|
|
31
30
|
{ labelField: 'label', valueField: 'value', lazy: false }
|
|
32
31
|
)
|
|
33
32
|
|
|
34
|
-
defineEmits<{ (e: 'input', value: unknown): void }>()
|
|
33
|
+
defineEmits<{ (e: 'input', value: unknown): void; (e: 'change', value: unknown): void }>()
|
|
35
34
|
|
|
36
35
|
const loading = ref(false)
|
|
37
36
|
const options = ref<Array<{ label: string; value: unknown }>>([])
|
|
37
|
+
const cachedParams = ref<string>('')
|
|
38
38
|
|
|
39
39
|
const onVisibleChange = (visible: boolean) => {
|
|
40
|
-
if (props.lazy && visible)
|
|
40
|
+
if (props.lazy && visible) {
|
|
41
|
+
const paramsKey = JSON.stringify(props.params ?? {})
|
|
42
|
+
if (paramsKey !== cachedParams.value || options.value.length === 0) {
|
|
43
|
+
fetchOptions()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
const fetchOptions = async () => {
|
|
@@ -59,11 +64,18 @@ const fetchOptions = async () => {
|
|
|
59
64
|
value: o[valueKey] ?? o.value,
|
|
60
65
|
}
|
|
61
66
|
})
|
|
67
|
+
cachedParams.value = JSON.stringify(props.params ?? {})
|
|
62
68
|
} finally {
|
|
63
69
|
loading.value = false
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
72
|
|
|
73
|
+
defineExpose({
|
|
74
|
+
options,
|
|
75
|
+
loading,
|
|
76
|
+
fetchOptions,
|
|
77
|
+
})
|
|
78
|
+
|
|
67
79
|
onMounted(() => {
|
|
68
80
|
if (!props.lazy) fetchOptions()
|
|
69
81
|
})
|
package/src/ProForm/ProForm.vue
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
:offset="schema.colProps?.offset ?? effectiveProps.baseColProps?.offset ?? 0" :data-field="schema.field">
|
|
11
11
|
<ProFormItem :schema="schema" :form-model="currentFormModel" :form-disabled="effectiveProps.disabled"
|
|
12
12
|
:auto-placeholder="effectiveProps.autoSetPlaceholder" :form-action-type="formActionRef" :colon="effectiveProps.colon"
|
|
13
|
-
:custom-components="formCustomComponents" :on-field-change="handleFieldChange"
|
|
13
|
+
:custom-components="formCustomComponents" :on-field-change="handleFieldChange"
|
|
14
|
+
:register-field-instance="registerFieldInstance">
|
|
14
15
|
<template v-if="slots[getSlotName(schema)]">
|
|
15
16
|
<slot :name="getSlotName(schema)" :model="currentFormModel" :schema="schema" :field="schema.field"
|
|
16
17
|
:values="currentFormModel" />
|
|
@@ -57,10 +58,11 @@
|
|
|
57
58
|
|
|
58
59
|
<script setup lang="ts">
|
|
59
60
|
import { ref, computed, watch, useSlots, onMounted, onUnmounted } from 'vue'
|
|
61
|
+
import type { ComponentPublicInstance } from 'vue'
|
|
60
62
|
import { useComponentSetting } from '../useComponentSetting'
|
|
61
63
|
import ProFormItem from './ProFormItem.vue'
|
|
62
64
|
import FormActions from './FormActions.vue'
|
|
63
|
-
import type { ProFormSchema, ProFormProps, FormActionType, ColEx, ScrollToFieldOptions, FormListeners } from '../types'
|
|
65
|
+
import type { ProFormSchema, ProFormProps, FormActionType, ColEx, ScrollToFieldOptions, FormListeners, ApiSelectInstance } from '../types'
|
|
64
66
|
|
|
65
67
|
const props = withDefaults(
|
|
66
68
|
defineProps<{
|
|
@@ -103,7 +105,7 @@ const props = withDefaults(
|
|
|
103
105
|
autoSetPlaceholder: true,
|
|
104
106
|
showSubmitButton: true,
|
|
105
107
|
showResetButton: true,
|
|
106
|
-
submitButtonText: '
|
|
108
|
+
submitButtonText: '查询',
|
|
107
109
|
resetButtonText: '重置',
|
|
108
110
|
submitButtonIcon: 'el-icon-search',
|
|
109
111
|
resetButtonIcon: 'el-icon-refresh-left',
|
|
@@ -132,6 +134,8 @@ const formModel = ref<Record<string, unknown>>({})
|
|
|
132
134
|
const formRules = ref<Record<string, unknown[]>>({})
|
|
133
135
|
const innerSchemas = ref<ProFormSchema[]>([])
|
|
134
136
|
const innerProps = ref<Partial<ProFormProps>>({})
|
|
137
|
+
/** 字段名 -> 组件实例映射(用于获取 api-select 等组件的内部状态) */
|
|
138
|
+
const fieldInstanceMap = ref<Map<string, ComponentPublicInstance>>(new Map())
|
|
135
139
|
|
|
136
140
|
/** Element UI 栅格断点 (px) */
|
|
137
141
|
const BREAKPOINTS = { xl: 1920, lg: 1200, md: 992, sm: 768 }
|
|
@@ -404,6 +408,39 @@ const setProps = async (formProps: Partial<ProFormProps>) => {
|
|
|
404
408
|
}
|
|
405
409
|
}
|
|
406
410
|
|
|
411
|
+
/** 注册组件实例(供 ProFormItem 调用) */
|
|
412
|
+
const registerFieldInstance = (field: string, instance: Record<string, unknown> | null) => {
|
|
413
|
+
if (instance) {
|
|
414
|
+
fieldInstanceMap.value.set(field, instance as unknown as ComponentPublicInstance)
|
|
415
|
+
} else {
|
|
416
|
+
fieldInstanceMap.value.delete(field)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/** 获取指定字段的组件实例 */
|
|
421
|
+
const getComponentInstance = (field: string): ComponentPublicInstance | null => {
|
|
422
|
+
return fieldInstanceMap.value.get(field) ?? null
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** 获取 api-select 字段的 options */
|
|
426
|
+
const getFieldOptions = (field: string): Array<{ label: string; value: unknown }> => {
|
|
427
|
+
const instance = fieldInstanceMap.value.get(field)
|
|
428
|
+
if (!instance) return []
|
|
429
|
+
const apiSelectInstance = instance as unknown as ApiSelectInstance
|
|
430
|
+
if (apiSelectInstance?.options) {
|
|
431
|
+
return apiSelectInstance.options
|
|
432
|
+
}
|
|
433
|
+
return []
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** 获取 api-select 字段的加载状态 */
|
|
437
|
+
const isFieldLoading = (field: string): boolean => {
|
|
438
|
+
const instance = fieldInstanceMap.value.get(field)
|
|
439
|
+
if (!instance) return false
|
|
440
|
+
const apiSelectInstance = instance as unknown as ApiSelectInstance
|
|
441
|
+
return apiSelectInstance?.loading ?? false
|
|
442
|
+
}
|
|
443
|
+
|
|
407
444
|
const formActionRef: FormActionType = {
|
|
408
445
|
getFieldsValue,
|
|
409
446
|
setFieldsValue,
|
|
@@ -417,9 +454,15 @@ const formActionRef: FormActionType = {
|
|
|
417
454
|
appendSchemaByField,
|
|
418
455
|
removeSchemaByField,
|
|
419
456
|
setProps,
|
|
457
|
+
getComponentInstance,
|
|
458
|
+
getFieldOptions,
|
|
459
|
+
isFieldLoading,
|
|
420
460
|
}
|
|
421
461
|
|
|
422
|
-
defineExpose(
|
|
462
|
+
defineExpose({
|
|
463
|
+
...formActionRef,
|
|
464
|
+
registerFieldInstance,
|
|
465
|
+
})
|
|
423
466
|
|
|
424
467
|
const syncSchemas = () => {
|
|
425
468
|
innerSchemas.value = [...(props.schemas ?? [])]
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
</el-select>
|
|
92
92
|
<ApiSelect
|
|
93
93
|
v-else-if="schema.component === 'api-select'"
|
|
94
|
+
ref="apiSelectRef"
|
|
94
95
|
:value="formModel[schema.field]"
|
|
95
96
|
:placeholder="schema.placeholder || (autoPlaceholder ? `请选择${schema.label}` : undefined)"
|
|
96
97
|
:disabled="effectiveDisabled"
|
|
@@ -178,7 +179,7 @@
|
|
|
178
179
|
</template>
|
|
179
180
|
|
|
180
181
|
<script setup lang="ts">
|
|
181
|
-
import { computed, useSlots, h } from 'vue'
|
|
182
|
+
import { computed, useSlots, h, ref, onMounted, onUnmounted } from 'vue'
|
|
182
183
|
import ApiSelect from './ApiSelect.vue'
|
|
183
184
|
import FormattedNumberInput from './FormattedNumberInput.vue'
|
|
184
185
|
import TreeSelect from './TreeSelect.vue'
|
|
@@ -201,8 +202,25 @@ const props = defineProps<{
|
|
|
201
202
|
onFieldChange?: (field: string, value: unknown) => void
|
|
202
203
|
/** 自定义组件映射(由 ProForm 传入) */
|
|
203
204
|
customComponents?: Record<string, unknown>
|
|
205
|
+
/** 注册字段实例(由 ProForm 传入) */
|
|
206
|
+
registerFieldInstance?: (field: string, instance: Record<string, unknown> | null) => void
|
|
204
207
|
}>()
|
|
205
208
|
|
|
209
|
+
/** ApiSelect 组件实例 ref */
|
|
210
|
+
const apiSelectRef = ref<Record<string, unknown> | null>(null)
|
|
211
|
+
|
|
212
|
+
onMounted(() => {
|
|
213
|
+
if (props.schema.component === 'api-select') {
|
|
214
|
+
props.registerFieldInstance?.(props.schema.field, apiSelectRef.value)
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
onUnmounted(() => {
|
|
219
|
+
if (props.schema.component === 'api-select') {
|
|
220
|
+
props.registerFieldInstance?.(props.schema.field, null)
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
|
|
206
224
|
const slots = useSlots()
|
|
207
225
|
|
|
208
226
|
const renderParams = computed<RenderCallbackParams>(() => ({
|
|
@@ -208,6 +208,8 @@
|
|
|
208
208
|
:page-sizes="pagination.pageSizes"
|
|
209
209
|
:page-size="pagination.pageSize"
|
|
210
210
|
:total="pagination.total"
|
|
211
|
+
:small="paginationSmall"
|
|
212
|
+
:background="paginationBackground"
|
|
211
213
|
:layout="(effectiveProps.pagination && typeof effectiveProps.pagination === 'object' ? effectiveProps.pagination.layout : null) || 'total, sizes, prev, pager, next, jumper'"
|
|
212
214
|
v-bind="(effectiveProps.pagination && typeof effectiveProps.pagination === 'object' && effectiveProps.pagination.props) || {}"
|
|
213
215
|
@size-change="handleSizeChange"
|
|
@@ -301,7 +303,7 @@ const props = withDefaults(
|
|
|
301
303
|
actionColumn?: Partial<ProColumn>
|
|
302
304
|
rowSelection?: { type?: 'checkbox' | 'radio'; width?: number; fixed?: 'left' | 'right'; getCheckboxProps?: (r: Record<string, unknown>) => { disabled?: boolean }; getRadioProps?: (r: Record<string, unknown>) => { disabled?: boolean } }
|
|
303
305
|
clearSelectOnPageChange?: boolean
|
|
304
|
-
pagination?: false | { pageSize?: number; pageSizes?: number[]; layout?: string; props?: Record<string, unknown> } | Record<string, unknown>
|
|
306
|
+
pagination?: false | { pageSize?: number; pageSizes?: number[]; layout?: string; small?: boolean; background?: boolean; props?: Record<string, unknown> } | Record<string, unknown>
|
|
305
307
|
tableSetting?: { redo?: boolean; size?: boolean; setting?: boolean; fullScreen?: boolean }
|
|
306
308
|
fetchSetting?: FetchSetting
|
|
307
309
|
beforeFetch?: (params: Record<string, unknown>) => Record<string, unknown>
|
|
@@ -362,21 +364,50 @@ const innerProps = ref<Partial<ProTableProps>>({})
|
|
|
362
364
|
const selectedRows = ref<Record<string, unknown>[]>([])
|
|
363
365
|
const showPaginationRef = ref<boolean | null>(null)
|
|
364
366
|
|
|
367
|
+
const { mergeSettings } = useComponentSetting()
|
|
368
|
+
const effectiveProps = computed(() => mergeSettings<ProTableProps>('ProTable', { ...props, ...innerProps.value }))
|
|
369
|
+
|
|
370
|
+
/** 从 effectiveProps.pagination 读取分页默认值(已通过深度合并) */
|
|
371
|
+
const defaultPagination = computed(() => {
|
|
372
|
+
const paginationConfig = effectiveProps.value.pagination
|
|
373
|
+
if (paginationConfig && typeof paginationConfig === 'object') {
|
|
374
|
+
return {
|
|
375
|
+
pageSize: (paginationConfig as Record<string, unknown>).pageSize ?? 10,
|
|
376
|
+
pageSizes: ((paginationConfig as Record<string, unknown>).pageSizes as number[]) ?? [10, 20, 50, 100],
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return { pageSize: 10, pageSizes: [10, 20, 50, 100] as number[] }
|
|
380
|
+
})
|
|
381
|
+
|
|
365
382
|
const pagination = ref({
|
|
366
383
|
page: 1,
|
|
367
|
-
pageSize:
|
|
368
|
-
pageSizes:
|
|
384
|
+
pageSize: defaultPagination.value.pageSize,
|
|
385
|
+
pageSizes: defaultPagination.value.pageSizes,
|
|
369
386
|
total: 0,
|
|
370
387
|
})
|
|
371
388
|
|
|
372
|
-
const { getSetting: getComponentSetting } = useComponentSetting()
|
|
373
|
-
const effectiveProps = computed(() => ({ ...getComponentSetting('ProTable'), ...props, ...innerProps.value }))
|
|
374
389
|
const showTitleBar = computed(() => !!effectiveProps.value.title || !!slots.tableTitle || !!slots.toolbar)
|
|
375
390
|
const showPagination = computed(() => {
|
|
376
391
|
if (showPaginationRef.value !== null) return showPaginationRef.value
|
|
377
392
|
return !!props.pagination && typeof props.pagination === 'object'
|
|
378
393
|
})
|
|
379
394
|
|
|
395
|
+
/** 分页 small 属性:从 pagination 配置或全局设置中读取 */
|
|
396
|
+
const paginationSmall = computed(() => {
|
|
397
|
+
if (effectiveProps.value.pagination && typeof effectiveProps.value.pagination === 'object') {
|
|
398
|
+
return !!(effectiveProps.value.pagination as Record<string, unknown>).small
|
|
399
|
+
}
|
|
400
|
+
return false
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
/** 分页 background 属性:从 pagination 配置或全局设置中读取 */
|
|
404
|
+
const paginationBackground = computed(() => {
|
|
405
|
+
if (effectiveProps.value.pagination && typeof effectiveProps.value.pagination === 'object') {
|
|
406
|
+
return !!(effectiveProps.value.pagination as Record<string, unknown>).background
|
|
407
|
+
}
|
|
408
|
+
return false
|
|
409
|
+
})
|
|
410
|
+
|
|
380
411
|
const rowKeyField = computed(() => effectiveProps.value.rowKey || 'id')
|
|
381
412
|
|
|
382
413
|
/** 选中行 key 集合(用于快速判断) */
|