Commit 41e6d94b3b64dc0d40b7ec57ecfaa4d966f202ae
1 parent
17e47e07
feat(demo): add search demo for apiSelect
添加ApiSelect的本地搜索和远程搜索例子
Showing
3 changed files
with
81 additions
and
27 deletions
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 | }, |