@aspire-ui/element-component-pro 1.0.14 → 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/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/element-component-pro.es.js +1092 -1057
- 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 +14 -0
- package/dist/style.css +1 -1
- package/dist/types/index.d.ts +19 -1
- package/package.json +1 -1
- package/src/ProForm/ApiSelect.vue +17 -5
- package/src/ProForm/ProForm.vue +47 -4
- package/src/ProForm/ProFormItem.vue +19 -1
- package/src/types/index.ts +14 -0
package/dist/index.d.ts
CHANGED
|
@@ -1700,6 +1700,7 @@ declare const _default: {
|
|
|
1700
1700
|
type: import('vue').PropType<import('./types').FormListeners>;
|
|
1701
1701
|
};
|
|
1702
1702
|
}>>> & import('vue').ShallowUnwrapRef<{
|
|
1703
|
+
registerFieldInstance: (field: string, instance: Record<string, unknown> | null) => void;
|
|
1703
1704
|
getFieldsValue: () => Record<string, unknown>;
|
|
1704
1705
|
setFieldsValue: (values: Record<string, unknown>) => Promise<void>;
|
|
1705
1706
|
resetFields: () => Promise<void>;
|
|
@@ -1712,6 +1713,12 @@ declare const _default: {
|
|
|
1712
1713
|
appendSchemaByField: (schema: import('./types').ProFormSchema, prefixField?: string, first?: boolean) => Promise<void>;
|
|
1713
1714
|
removeSchemaByField: (field: string | string[]) => Promise<void>;
|
|
1714
1715
|
setProps: (props: Partial<import('./types').ProFormProps>) => Promise<void>;
|
|
1716
|
+
getComponentInstance: (field: string) => import('vue').ComponentPublicInstance | null;
|
|
1717
|
+
getFieldOptions: (field: string) => Array<{
|
|
1718
|
+
label: string;
|
|
1719
|
+
value: unknown;
|
|
1720
|
+
}>;
|
|
1721
|
+
isFieldLoading: (field: string) => boolean;
|
|
1715
1722
|
}> & import('vue/types/v3-component-options').ExtractComputedReturns<{}> & import('vue').ComponentCustomProperties & Readonly<import('vue').ExtractPropTypes<{
|
|
1716
1723
|
disabled: {
|
|
1717
1724
|
type: import('vue').PropType<boolean>;
|
|
@@ -1945,6 +1952,7 @@ declare const _default: {
|
|
|
1945
1952
|
type: import('vue').PropType<import('./types').FormListeners>;
|
|
1946
1953
|
};
|
|
1947
1954
|
}>>, {
|
|
1955
|
+
registerFieldInstance: (field: string, instance: Record<string, unknown> | null) => void;
|
|
1948
1956
|
getFieldsValue: () => Record<string, unknown>;
|
|
1949
1957
|
setFieldsValue: (values: Record<string, unknown>) => Promise<void>;
|
|
1950
1958
|
resetFields: () => Promise<void>;
|
|
@@ -1957,6 +1965,12 @@ declare const _default: {
|
|
|
1957
1965
|
appendSchemaByField: (schema: import('./types').ProFormSchema, prefixField?: string, first?: boolean) => Promise<void>;
|
|
1958
1966
|
removeSchemaByField: (field: string | string[]) => Promise<void>;
|
|
1959
1967
|
setProps: (props: Partial<import('./types').ProFormProps>) => Promise<void>;
|
|
1968
|
+
getComponentInstance: (field: string) => import('vue').ComponentPublicInstance | null;
|
|
1969
|
+
getFieldOptions: (field: string) => Array<{
|
|
1970
|
+
label: string;
|
|
1971
|
+
value: unknown;
|
|
1972
|
+
}>;
|
|
1973
|
+
isFieldLoading: (field: string) => boolean;
|
|
1960
1974
|
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
1961
1975
|
submit: (values: Record<string, unknown>) => void;
|
|
1962
1976
|
reset: () => void;
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
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-
|
|
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?];
|
package/package.json
CHANGED
|
@@ -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>(() => ({
|
package/src/types/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VNode } from 'vue'
|
|
2
|
+
import type { ComponentPublicInstance } from 'vue'
|
|
2
3
|
|
|
3
4
|
/** 栅格配置 */
|
|
4
5
|
export interface ColEx {
|
|
@@ -31,6 +32,13 @@ export interface ScrollToFieldOptions {
|
|
|
31
32
|
inline?: ScrollLogicalPosition
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
/** ApiSelect 暴露的实例类型 */
|
|
36
|
+
export interface ApiSelectInstance {
|
|
37
|
+
options: Array<{ label: string; value: unknown }>
|
|
38
|
+
loading: boolean
|
|
39
|
+
fetchOptions: () => Promise<void>
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
/** 表单操作类型(参考 Vben Admin FormActionType) */
|
|
35
43
|
export interface FormActionType {
|
|
36
44
|
getFieldsValue: () => Record<string, unknown>
|
|
@@ -45,6 +53,12 @@ export interface FormActionType {
|
|
|
45
53
|
appendSchemaByField: (schema: ProFormSchema, prefixField?: string, first?: boolean) => Promise<void>
|
|
46
54
|
removeSchemaByField: (field: string | string[]) => Promise<void>
|
|
47
55
|
setProps: (props: Partial<ProFormProps>) => Promise<void>
|
|
56
|
+
/** 获取指定字段的组件实例 */
|
|
57
|
+
getComponentInstance: (field: string) => ComponentPublicInstance | null
|
|
58
|
+
/** 获取 api-select 字段的 options */
|
|
59
|
+
getFieldOptions: (field: string) => Array<{ label: string; value: unknown }>
|
|
60
|
+
/** 获取 api-select 字段的加载状态 */
|
|
61
|
+
isFieldLoading: (field: string) => boolean
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
/** 时间字段映射 [表单字段, [开始字段, 结束字段], 格式?] */
|