Skip to content

Commit a8c4786

Browse files
authored
feat: api-component support autoSelect prop (#5931)
* feat: api-component support autoSelect prop * docs: add version requirement
1 parent 2971ccc commit a8c4786

File tree

3 files changed

+66
-21
lines changed

3 files changed

+66
-21
lines changed

docs/src/components/common-ui/vben-api-component.md

+30-20
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,36 @@ function fetchApi(): Promise<Record<string, any>> {
131131

132132
### Props
133133

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

155165
### Methods
156166

packages/effects/common-ui/src/components/api-component/api-component.vue

+35-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ interface Props {
5454
visibleEvent?: string;
5555
/** 组件的v-model属性名,默认为modelValue。部分组件可能为value */
5656
modelPropName?: string;
57+
/**
58+
* 自动选择
59+
* - `first`:自动选择第一个选项
60+
* - `last`:自动选择最后一个选项
61+
* - `one`: 当请求的结果只有一个选项时,自动选择该选项
62+
* - false:不自动选择(默认)
63+
*/
64+
autoSelect?: 'first' | 'last' | 'one' | false;
5765
}
5866
5967
defineOptions({ name: 'ApiComponent', inheritAttrs: false });
@@ -74,14 +82,15 @@ const props = withDefaults(defineProps<Props>(), {
7482
afterFetch: undefined,
7583
modelPropName: 'modelValue',
7684
api: undefined,
85+
autoSelect: false,
7786
options: () => [],
7887
});
7988
8089
const emit = defineEmits<{
8190
optionsChange: [OptionsItem[]];
8291
}>();
8392
84-
const modelValue = defineModel({ default: '' });
93+
const modelValue = defineModel<any>({ default: undefined });
8594
8695
const attrs = useAttrs();
8796
const innerParams = ref({});
@@ -194,6 +203,31 @@ watch(
194203
);
195204
196205
function emitChange() {
206+
if (
207+
modelValue.value === undefined &&
208+
props.autoSelect &&
209+
unref(getOptions).length > 0
210+
) {
211+
let firstOption;
212+
switch (props.autoSelect) {
213+
case 'first': {
214+
firstOption = unref(getOptions)[0];
215+
break;
216+
}
217+
case 'last': {
218+
firstOption = unref(getOptions)[unref(getOptions).length - 1];
219+
break;
220+
}
221+
case 'one': {
222+
if (unref(getOptions).length === 1) {
223+
firstOption = unref(getOptions)[0];
224+
}
225+
break;
226+
}
227+
}
228+
229+
if (firstOption) modelValue.value = firstOption[props.valueField];
230+
}
197231
emit('optionsChange', unref(getOptions));
198232
}
199233
const componentRef = ref();

playground/src/views/examples/form/basic.vue

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ const [BaseForm, baseFormApi] = useVbenForm({
7474
},
7575
// 菜单接口
7676
api: getAllMenusApi,
77+
autoSelect: 'first',
7778
},
7879
// 字段名
7980
fieldName: 'api',

0 commit comments

Comments
 (0)