feat: api-component support autoSelect prop (#5931)

* feat: api-component support autoSelect prop

* docs: add version requirement
This commit is contained in:
Netfan 2025-04-12 14:02:35 +08:00 committed by GitHub
parent 2971ccc0b7
commit a8c4786311
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 66 additions and 21 deletions

View File

@ -131,26 +131,36 @@ function fetchApi(): Promise<Record<string, any>> {
### Props ### Props
| 属性名 | 描述 | 类型 | 默认值 | | 属性名 | 描述 | 类型 | 默认值 | 版本要求 |
| --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| modelValue(v-model) | 当前值 | `any` | - | | modelValue(v-model) | 当前值 | `any` | - | - |
| component | 欲包装的组件(以下称为目标组件) | `Component` | - | | component | 欲包装的组件(以下称为目标组件) | `Component` | - | - |
| numberToString | 是否将value从数字转为string | `boolean` | `false` | | numberToString | 是否将value从数字转为string | `boolean` | `false` | - |
| api | 获取数据的函数 | `(arg?: any) => Promise<OptionsItem[] \| Record<string, any>>` | - | | api | 获取数据的函数 | `(arg?: any) => Promise<OptionsItem[] \| Record<string, any>>` | - | - |
| params | 传递给api的参数 | `Record<string, any>` | - | | params | 传递给api的参数 | `Record<string, any>` | - | - |
| resultField | 从api返回的结果中提取options数组的字段名 | `string` | - | | resultField | 从api返回的结果中提取options数组的字段名 | `string` | - | - |
| labelField | label字段名 | `string` | `label` | | labelField | label字段名 | `string` | `label` | - |
| childrenField | 子级数据字段名,需要层级数据的组件可用 | `string` | `` | | childrenField | 子级数据字段名,需要层级数据的组件可用 | `string` | `` | - |
| valueField | value字段名 | `string` | `value` | | valueField | value字段名 | `string` | `value` | - |
| optionsPropName | 目标组件接收options数据的属性名称 | `string` | `options` | | optionsPropName | 目标组件接收options数据的属性名称 | `string` | `options` | - |
| modelPropName | 目标组件的双向绑定属性名默认为modelValue。部分组件可能为value | `string` | `modelValue` | | modelPropName | 目标组件的双向绑定属性名默认为modelValue。部分组件可能为value | `string` | `modelValue` | - |
| immediate | 是否立即调用api | `boolean` | `true` | | immediate | 是否立即调用api | `boolean` | `true` | - |
| alwaysLoad | 每次`visibleEvent`事件发生时都重新请求数据 | `boolean` | `false` | | alwaysLoad | 每次`visibleEvent`事件发生时都重新请求数据 | `boolean` | `false` | - |
| beforeFetch | 在api请求之前的回调函数 | `AnyPromiseFunction<any, any>` | - | | beforeFetch | 在api请求之前的回调函数 | `AnyPromiseFunction<any, any>` | - | - |
| afterFetch | 在api请求之后的回调函数 | `AnyPromiseFunction<any, any>` | - | | afterFetch | 在api请求之后的回调函数 | `AnyPromiseFunction<any, any>` | - | - |
| options | 直接传入选项数据也作为api返回空数据时的后备数据 | `OptionsItem[]` | - | | options | 直接传入选项数据也作为api返回空数据时的后备数据 | `OptionsItem[]` | - | - |
| visibleEvent | 触发重新请求数据的事件名 | `string` | - | | visibleEvent | 触发重新请求数据的事件名 | `string` | - | - |
| loadingSlot | 目标组件的插槽名称,用来显示一个"加载中"的图标 | `string` | - | | loadingSlot | 目标组件的插槽名称,用来显示一个"加载中"的图标 | `string` | - | - |
| autoSelect | 自动设置选项 | `'first' \| 'last' \| 'none'\| false` | `false` | >5.5.4 |
#### autoSelect 自动设置选项
如果当前值为undefined在选项数据成功加载之后自动从备选项中选择一个作为当前值。默认值为`false`,即不自动选择选项。注意:该属性不应用于多选组件。可选值有:
- `first`:自动选择第一个选项
- `last`:自动选择最后一个选项
- `one`:有且仅有一个选项时,自动选择它
- false不自动选择选项
### Methods ### Methods

View File

@ -54,6 +54,14 @@ interface Props {
visibleEvent?: string; visibleEvent?: string;
/** 组件的v-model属性名默认为modelValue。部分组件可能为value */ /** 组件的v-model属性名默认为modelValue。部分组件可能为value */
modelPropName?: string; modelPropName?: string;
/**
* 自动选择
* - `first`自动选择第一个选项
* - `last`自动选择最后一个选项
* - `one`: 当请求的结果只有一个选项时自动选择该选项
* - false不自动选择(默认)
*/
autoSelect?: 'first' | 'last' | 'one' | false;
} }
defineOptions({ name: 'ApiComponent', inheritAttrs: false }); defineOptions({ name: 'ApiComponent', inheritAttrs: false });
@ -74,6 +82,7 @@ const props = withDefaults(defineProps<Props>(), {
afterFetch: undefined, afterFetch: undefined,
modelPropName: 'modelValue', modelPropName: 'modelValue',
api: undefined, api: undefined,
autoSelect: false,
options: () => [], options: () => [],
}); });
@ -81,7 +90,7 @@ const emit = defineEmits<{
optionsChange: [OptionsItem[]]; optionsChange: [OptionsItem[]];
}>(); }>();
const modelValue = defineModel({ default: '' }); const modelValue = defineModel<any>({ default: undefined });
const attrs = useAttrs(); const attrs = useAttrs();
const innerParams = ref({}); const innerParams = ref({});
@ -194,6 +203,31 @@ watch(
); );
function emitChange() { function emitChange() {
if (
modelValue.value === undefined &&
props.autoSelect &&
unref(getOptions).length > 0
) {
let firstOption;
switch (props.autoSelect) {
case 'first': {
firstOption = unref(getOptions)[0];
break;
}
case 'last': {
firstOption = unref(getOptions)[unref(getOptions).length - 1];
break;
}
case 'one': {
if (unref(getOptions).length === 1) {
firstOption = unref(getOptions)[0];
}
break;
}
}
if (firstOption) modelValue.value = firstOption[props.valueField];
}
emit('optionsChange', unref(getOptions)); emit('optionsChange', unref(getOptions));
} }
const componentRef = ref(); const componentRef = ref();

View File

@ -74,6 +74,7 @@ const [BaseForm, baseFormApi] = useVbenForm({
}, },
// //
api: getAllMenusApi, api: getAllMenusApi,
autoSelect: 'first',
}, },
// //
fieldName: 'api', fieldName: 'api',