Commit 41e6d94b3b64dc0d40b7ec57ecfaa4d966f202ae

Authored by 无木
1 parent 17e47e07

feat(demo): add search demo for apiSelect

添加ApiSelect的本地搜索和远程搜索例子
mock/demo/select-demo.ts
1 import { MockMethod } from 'vite-plugin-mock'; 1 import { MockMethod } from 'vite-plugin-mock';
2 import { resultSuccess } from '../_util'; 2 import { resultSuccess } from '../_util';
3 3
4 -const list: any[] = [];  
5 -const demoList = (() => { 4 +const demoList = (keyword) => {
6 const result = { 5 const result = {
7 - list: list, 6 + list: [],
8 }; 7 };
9 for (let index = 0; index < 20; index++) { 8 for (let index = 0; index < 20; index++) {
10 result.list.push({ 9 result.list.push({
11 - name: `选项${index}`, 10 + name: `${keyword ?? ''}选项${index}`,
12 id: `${index}`, 11 id: `${index}`,
13 }); 12 });
14 } 13 }
15 return result; 14 return result;
16 -})(); 15 +};
17 16
18 export default [ 17 export default [
19 { 18 {
20 url: '/basic-api/select/getDemoOptions', 19 url: '/basic-api/select/getDemoOptions',
21 timeout: 1000, 20 timeout: 1000,
22 - method: 'post', 21 + method: 'get',
23 response: ({ query }) => { 22 response: ({ query }) => {
24 - console.log(query);  
25 - return resultSuccess(demoList); 23 + const { keyword } = query;
  24 + console.log(keyword);
  25 + return resultSuccess(demoList(keyword));
26 }, 26 },
27 }, 27 },
28 ] as MockMethod[]; 28 ] as MockMethod[];
src/api/demo/select.ts
@@ -8,4 +8,4 @@ enum Api { @@ -8,4 +8,4 @@ enum Api {
8 * @description: Get sample options value 8 * @description: Get sample options value
9 */ 9 */
10 export const optionsListApi = (params?: selectParams) => 10 export const optionsListApi = (params?: selectParams) =>
11 - defHttp.post<DemoOptionsItem[]>({ url: Api.OPTIONS_LIST, params }); 11 + defHttp.get<DemoOptionsItem[]>({ url: Api.OPTIONS_LIST, params });
src/views/demo/form/index.vue
@@ -3,22 +3,49 @@ @@ -3,22 +3,49 @@
3 <CollapseContainer title="基础示例"> 3 <CollapseContainer title="基础示例">
4 <BasicForm 4 <BasicForm
5 autoFocusFirstItem 5 autoFocusFirstItem
6 - :labelWidth="100" 6 + :labelWidth="200"
7 :schemas="schemas" 7 :schemas="schemas"
8 :actionColOptions="{ span: 24 }" 8 :actionColOptions="{ span: 24 }"
9 @submit="handleSubmit" 9 @submit="handleSubmit"
10 - /> 10 + @reset="handleReset"
  11 + >
  12 + <template #localSearch="{ model, field }">
  13 + <ApiSelect
  14 + :api="optionsListApi"
  15 + showSearch
  16 + v-model:value="model[field]"
  17 + optionFilterProp="label"
  18 + resultField="list"
  19 + labelField="name"
  20 + valueField="id"
  21 + />
  22 + </template>
  23 + <template #remoteSearch="{ model, field }">
  24 + <ApiSelect
  25 + :api="optionsListApi"
  26 + showSearch
  27 + v-model:value="model[field]"
  28 + :filterOption="false"
  29 + resultField="list"
  30 + labelField="name"
  31 + valueField="id"
  32 + :params="searchParams"
  33 + @search="onSearch"
  34 + />
  35 + </template>
  36 + </BasicForm>
11 </CollapseContainer> 37 </CollapseContainer>
12 </PageWrapper> 38 </PageWrapper>
13 </template> 39 </template>
14 <script lang="ts"> 40 <script lang="ts">
15 - import { defineComponent, ref } from 'vue';  
16 - import { BasicForm, FormSchema } from '/@/components/Form/index';  
17 - import { CollapseContainer } from '/@/components/Container/index'; 41 + import { computed, defineComponent, unref, ref } from 'vue';
  42 + import { BasicForm, FormSchema, ApiSelect } from '/@/components/Form/index';
  43 + import { CollapseContainer } from '/@/components/Container';
18 import { useMessage } from '/@/hooks/web/useMessage'; 44 import { useMessage } from '/@/hooks/web/useMessage';
19 import { PageWrapper } from '/@/components/Page'; 45 import { PageWrapper } from '/@/components/Page';
20 46
21 import { optionsListApi } from '/@/api/demo/select'; 47 import { optionsListApi } from '/@/api/demo/select';
  48 + import { useDebounceFn } from '@vueuse/core';
22 49
23 const provincesOptions = [ 50 const provincesOptions = [
24 { 51 {
@@ -265,11 +292,10 @@ @@ -265,11 +292,10 @@
265 ], 292 ],
266 }, 293 },
267 }, 294 },
268 -  
269 { 295 {
270 field: 'field30', 296 field: 'field30',
271 component: 'ApiSelect', 297 component: 'ApiSelect',
272 - label: '远程下拉', 298 + label: '懒加载远程下拉',
273 required: true, 299 required: true,
274 componentProps: { 300 componentProps: {
275 // more details see /src/components/Form/src/components/ApiSelect.vue 301 // more details see /src/components/Form/src/components/ApiSelect.vue
@@ -277,15 +303,6 @@ @@ -277,15 +303,6 @@
277 params: { 303 params: {
278 id: 1, 304 id: 1,
279 }, 305 },
280 - // use [res.data.result.list] (no res.data.result) as options datas  
281 - // result: {  
282 - // list: [  
283 - // {  
284 - // name: "选项0",  
285 - // id: "0"  
286 - // },  
287 - // ]  
288 - // }  
289 resultField: 'list', 306 resultField: 'list',
290 // use name as label 307 // use name as label
291 labelField: 'name', 308 labelField: 'name',
@@ -304,7 +321,30 @@ @@ -304,7 +321,30 @@
304 colProps: { 321 colProps: {
305 span: 8, 322 span: 8,
306 }, 323 },
307 - // set default value 324 + defaultValue: '0',
  325 + },
  326 + {
  327 + field: 'field31',
  328 + component: 'Input',
  329 + label: '下拉本地搜索',
  330 + helpMessage: ['ApiSelect组件', '远程数据源本地搜索', '只发起一次请求获取所有选项'],
  331 + required: true,
  332 + slot: 'localSearch',
  333 + colProps: {
  334 + span: 8,
  335 + },
  336 + defaultValue: '0',
  337 + },
  338 + {
  339 + field: 'field32',
  340 + component: 'Input',
  341 + label: '下拉远程搜索',
  342 + helpMessage: ['ApiSelect组件', '将关键词发送到接口进行远程搜索'],
  343 + required: true,
  344 + slot: 'remoteSearch',
  345 + colProps: {
  346 + span: 8,
  347 + },
308 defaultValue: '0', 348 defaultValue: '0',
309 }, 349 },
310 { 350 {
@@ -394,12 +434,26 @@ @@ -394,12 +434,26 @@
394 ]; 434 ];
395 435
396 export default defineComponent({ 436 export default defineComponent({
397 - components: { BasicForm, CollapseContainer, PageWrapper }, 437 + components: { BasicForm, CollapseContainer, PageWrapper, ApiSelect },
398 setup() { 438 setup() {
399 const check = ref(null); 439 const check = ref(null);
400 const { createMessage } = useMessage(); 440 const { createMessage } = useMessage();
  441 + const keyword = ref<string>('');
  442 + const searchParams = computed<Recordable>(() => {
  443 + return { keyword: unref(keyword) };
  444 + });
  445 +
  446 + function onSearch(value: string) {
  447 + keyword.value = value;
  448 + }
401 return { 449 return {
402 schemas, 450 schemas,
  451 + optionsListApi,
  452 + onSearch: useDebounceFn(onSearch, 300),
  453 + searchParams,
  454 + handleReset: () => {
  455 + keyword.value = '';
  456 + },
403 handleSubmit: (values: any) => { 457 handleSubmit: (values: any) => {
404 createMessage.success('click search,values:' + JSON.stringify(values)); 458 createMessage.success('click search,values:' + JSON.stringify(values));
405 }, 459 },