Commit 97fe8e2058147a331442340b209eee596f6033db
Committed by
GitHub
1 parent
5c491a42
feat(ApiCascader): add asynchronous cascader component (#1321)
Showing
8 changed files
with
622 additions
and
1 deletions
mock/demo/api-cascader.ts
0 → 100644
1 | +import { MockMethod } from 'vite-plugin-mock'; | |
2 | +import { resultSuccess } from '../_util'; | |
3 | + | |
4 | +const areaList: any[] = [ | |
5 | + { | |
6 | + id: '530825900854620160', | |
7 | + code: '430000', | |
8 | + parentCode: '100000', | |
9 | + levelType: 1, | |
10 | + name: '湖南省', | |
11 | + province: '湖南省', | |
12 | + city: null, | |
13 | + district: null, | |
14 | + town: null, | |
15 | + village: null, | |
16 | + parentPath: '430000', | |
17 | + createTime: '2020-11-30 15:47:31', | |
18 | + updateTime: '2020-11-30 16:33:42', | |
19 | + customized: false, | |
20 | + usable: true, | |
21 | + }, | |
22 | + { | |
23 | + id: '530825900883980288', | |
24 | + code: '430100', | |
25 | + parentCode: '430000', | |
26 | + levelType: 2, | |
27 | + name: '长沙市', | |
28 | + province: '湖南省', | |
29 | + city: '长沙市', | |
30 | + district: null, | |
31 | + town: null, | |
32 | + village: null, | |
33 | + parentPath: '430000,430100', | |
34 | + createTime: '2020-11-30 15:47:31', | |
35 | + updateTime: '2020-11-30 16:33:42', | |
36 | + customized: false, | |
37 | + usable: true, | |
38 | + }, | |
39 | + { | |
40 | + id: '530825900951089152', | |
41 | + code: '430102', | |
42 | + parentCode: '430100', | |
43 | + levelType: 3, | |
44 | + name: '芙蓉区', | |
45 | + province: '湖南省', | |
46 | + city: '长沙市', | |
47 | + district: '芙蓉区', | |
48 | + town: null, | |
49 | + village: null, | |
50 | + parentPath: '430000,430100,430102', | |
51 | + createTime: '2020-11-30 15:47:31', | |
52 | + updateTime: '2020-11-30 16:33:42', | |
53 | + customized: false, | |
54 | + usable: true, | |
55 | + }, | |
56 | + { | |
57 | + id: '530825901014003712', | |
58 | + code: '430104', | |
59 | + parentCode: '430100', | |
60 | + levelType: 3, | |
61 | + name: '岳麓区', | |
62 | + province: '湖南省', | |
63 | + city: '长沙市', | |
64 | + district: '岳麓区', | |
65 | + town: null, | |
66 | + village: null, | |
67 | + parentPath: '430000,430100,430104', | |
68 | + createTime: '2020-11-30 15:47:31', | |
69 | + updateTime: '2020-11-30 16:33:42', | |
70 | + customized: false, | |
71 | + usable: true, | |
72 | + }, | |
73 | + { | |
74 | + id: '530825900988837888', | |
75 | + code: '430103', | |
76 | + parentCode: '430100', | |
77 | + levelType: 3, | |
78 | + name: '天心区', | |
79 | + province: '湖南省', | |
80 | + city: '长沙市', | |
81 | + district: '天心区', | |
82 | + town: null, | |
83 | + village: null, | |
84 | + parentPath: '430000,430100,430103', | |
85 | + createTime: '2020-11-30 15:47:31', | |
86 | + updateTime: '2020-11-30 16:33:42', | |
87 | + customized: false, | |
88 | + usable: true, | |
89 | + }, | |
90 | + { | |
91 | + id: '530826672489115648', | |
92 | + code: '430103002', | |
93 | + parentCode: '430103', | |
94 | + levelType: 4, | |
95 | + name: '坡子街街道', | |
96 | + province: '湖南省', | |
97 | + city: '长沙市', | |
98 | + district: '天心区', | |
99 | + town: '坡子街街道', | |
100 | + village: null, | |
101 | + parentPath: '430000,430100,430103,430103002', | |
102 | + createTime: '2020-11-30 15:47:31', | |
103 | + updateTime: '2020-12-14 15:26:43', | |
104 | + customized: false, | |
105 | + usable: true, | |
106 | + }, | |
107 | + { | |
108 | + id: '530840241171607552', | |
109 | + code: '430103002001', | |
110 | + parentCode: '430103002', | |
111 | + levelType: 5, | |
112 | + name: '八角亭社区', | |
113 | + province: '湖南省', | |
114 | + city: '长沙市', | |
115 | + district: '天心区', | |
116 | + town: '坡子街街道', | |
117 | + village: '八角亭社区', | |
118 | + parentPath: '430000,430100,430103,430103002,430103002001', | |
119 | + createTime: '2020-11-30 15:47:31', | |
120 | + updateTime: '2021-01-20 14:07:23', | |
121 | + customized: false, | |
122 | + usable: true, | |
123 | + }, | |
124 | + { | |
125 | + id: '530840241200967680', | |
126 | + code: '430103002002', | |
127 | + parentCode: '430103002', | |
128 | + levelType: 5, | |
129 | + name: '西牌楼社区', | |
130 | + province: '湖南省', | |
131 | + city: '长沙市', | |
132 | + district: '天心区', | |
133 | + town: '坡子街街道', | |
134 | + village: '西牌楼社区', | |
135 | + parentPath: '430000,430100,430103,430103002,430103002002', | |
136 | + createTime: '2020-11-30 15:47:31', | |
137 | + updateTime: '2020-11-30 17:30:41', | |
138 | + customized: false, | |
139 | + usable: true, | |
140 | + }, | |
141 | + { | |
142 | + id: '530840241230327808', | |
143 | + code: '430103002003', | |
144 | + parentCode: '430103002', | |
145 | + levelType: 5, | |
146 | + name: '太平街社区', | |
147 | + province: '湖南省', | |
148 | + city: '长沙市', | |
149 | + district: '天心区', | |
150 | + town: '坡子街街道', | |
151 | + village: '太平街社区', | |
152 | + parentPath: '430000,430100,430103,430103002,430103002003', | |
153 | + createTime: '2020-11-30 15:47:31', | |
154 | + updateTime: '2020-11-30 17:30:41', | |
155 | + customized: false, | |
156 | + usable: true, | |
157 | + }, | |
158 | + { | |
159 | + id: '530840241259687936', | |
160 | + code: '430103002005', | |
161 | + parentCode: '430103002', | |
162 | + levelType: 5, | |
163 | + name: '坡子街社区', | |
164 | + province: '湖南省', | |
165 | + city: '长沙市', | |
166 | + district: '天心区', | |
167 | + town: '坡子街街道', | |
168 | + village: '坡子街社区', | |
169 | + parentPath: '430000,430100,430103,430103002,430103002005', | |
170 | + createTime: '2020-11-30 15:47:31', | |
171 | + updateTime: '2020-11-30 17:30:41', | |
172 | + customized: false, | |
173 | + usable: true, | |
174 | + }, | |
175 | + { | |
176 | + id: '530840241284853760', | |
177 | + code: '430103002006', | |
178 | + parentCode: '430103002', | |
179 | + levelType: 5, | |
180 | + name: '青山祠社区', | |
181 | + province: '湖南省', | |
182 | + city: '长沙市', | |
183 | + district: '天心区', | |
184 | + town: '坡子街街道', | |
185 | + village: '青山祠社区', | |
186 | + parentPath: '430000,430100,430103,430103002,430103002006', | |
187 | + createTime: '2020-11-30 15:47:31', | |
188 | + updateTime: '2020-11-30 17:30:41', | |
189 | + customized: false, | |
190 | + usable: true, | |
191 | + }, | |
192 | + { | |
193 | + id: '530840241310019584', | |
194 | + code: '430103002007', | |
195 | + parentCode: '430103002', | |
196 | + levelType: 5, | |
197 | + name: '沙河社区', | |
198 | + province: '湖南省', | |
199 | + city: '长沙市', | |
200 | + district: '天心区', | |
201 | + town: '坡子街街道', | |
202 | + village: '沙河社区', | |
203 | + parentPath: '430000,430100,430103,430103002,430103002007', | |
204 | + createTime: '2020-11-30 15:47:31', | |
205 | + updateTime: '2020-11-30 17:30:41', | |
206 | + customized: false, | |
207 | + usable: true, | |
208 | + }, | |
209 | + { | |
210 | + id: '530840241381322752', | |
211 | + code: '430103002008', | |
212 | + parentCode: '430103002', | |
213 | + levelType: 5, | |
214 | + name: '碧湘社区', | |
215 | + province: '湖南省', | |
216 | + city: '长沙市', | |
217 | + district: '天心区', | |
218 | + town: '坡子街街道', | |
219 | + village: '碧湘社区', | |
220 | + parentPath: '430000,430100,430103,430103002,430103002008', | |
221 | + createTime: '2020-11-30 15:47:31', | |
222 | + updateTime: '2020-11-30 17:30:41', | |
223 | + customized: false, | |
224 | + usable: true, | |
225 | + }, | |
226 | + { | |
227 | + id: '530840241410682880', | |
228 | + code: '430103002009', | |
229 | + parentCode: '430103002', | |
230 | + levelType: 5, | |
231 | + name: '创远社区', | |
232 | + province: '湖南省', | |
233 | + city: '长沙市', | |
234 | + district: '天心区', | |
235 | + town: '坡子街街道', | |
236 | + village: '创远社区', | |
237 | + parentPath: '430000,430100,430103,430103002,430103002009', | |
238 | + createTime: '2020-11-30 15:47:31', | |
239 | + updateTime: '2020-11-30 17:30:41', | |
240 | + customized: false, | |
241 | + usable: true, | |
242 | + }, | |
243 | + { | |
244 | + id: '530840241431654400', | |
245 | + code: '430103002010', | |
246 | + parentCode: '430103002', | |
247 | + levelType: 5, | |
248 | + name: '楚湘社区', | |
249 | + province: '湖南省', | |
250 | + city: '长沙市', | |
251 | + district: '天心区', | |
252 | + town: '坡子街街道', | |
253 | + village: '楚湘社区', | |
254 | + parentPath: '430000,430100,430103,430103002,430103002010', | |
255 | + createTime: '2020-11-30 15:47:31', | |
256 | + updateTime: '2020-11-30 17:30:41', | |
257 | + customized: false, | |
258 | + usable: true, | |
259 | + }, | |
260 | + { | |
261 | + id: '530840241465208832', | |
262 | + code: '430103002011', | |
263 | + parentCode: '430103002', | |
264 | + levelType: 5, | |
265 | + name: '西湖社区', | |
266 | + province: '湖南省', | |
267 | + city: '长沙市', | |
268 | + district: '天心区', | |
269 | + town: '坡子街街道', | |
270 | + village: '西湖社区', | |
271 | + parentPath: '430000,430100,430103,430103002,430103002011', | |
272 | + createTime: '2020-11-30 15:47:31', | |
273 | + updateTime: '2020-11-30 17:30:41', | |
274 | + customized: false, | |
275 | + usable: true, | |
276 | + }, | |
277 | + { | |
278 | + id: '530840241502957568', | |
279 | + code: '430103002012', | |
280 | + parentCode: '430103002', | |
281 | + levelType: 5, | |
282 | + name: '登仁桥社区', | |
283 | + province: '湖南省', | |
284 | + city: '长沙市', | |
285 | + district: '天心区', | |
286 | + town: '坡子街街道', | |
287 | + village: '登仁桥社区', | |
288 | + parentPath: '430000,430100,430103,430103002,430103002012', | |
289 | + createTime: '2020-11-30 15:47:31', | |
290 | + updateTime: '2020-11-30 17:30:41', | |
291 | + customized: false, | |
292 | + usable: true, | |
293 | + }, | |
294 | + { | |
295 | + id: '530840241553289216', | |
296 | + code: '430103002013', | |
297 | + parentCode: '430103002', | |
298 | + levelType: 5, | |
299 | + name: '文庙坪社区', | |
300 | + province: '湖南省', | |
301 | + city: '长沙市', | |
302 | + district: '天心区', | |
303 | + town: '坡子街街道', | |
304 | + village: '文庙坪社区', | |
305 | + parentPath: '430000,430100,430103,430103002,430103002013', | |
306 | + createTime: '2020-11-30 15:47:31', | |
307 | + updateTime: '2020-11-30 17:30:41', | |
308 | + customized: false, | |
309 | + usable: true, | |
310 | + }, | |
311 | +]; | |
312 | +export default [ | |
313 | + { | |
314 | + url: '/basic-api/cascader/getAreaRecord', | |
315 | + timeout: 1000, | |
316 | + method: 'post', | |
317 | + response: ({ body }) => { | |
318 | + const { parentCode } = body || {}; | |
319 | + if (!parentCode) { | |
320 | + return resultSuccess(areaList.filter((it) => it.code === '430000')); | |
321 | + } | |
322 | + return resultSuccess(areaList.filter((it) => it.parentCode === parentCode)); | |
323 | + }, | |
324 | + }, | |
325 | +] as MockMethod[]; | ... | ... |
src/api/demo/cascader.ts
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | |
2 | +import { AreaModel, AreaParams } from '/@/api/demo/model/areaModel'; | |
3 | + | |
4 | +enum Api { | |
5 | + AREA_RECORD = '/cascader/getAreaRecord', | |
6 | +} | |
7 | + | |
8 | +export const areaRecord = (data: AreaParams) => | |
9 | + defHttp.post<AreaModel>({ url: Api.AREA_RECORD, data }); | ... | ... |
src/api/demo/model/areaModel.ts
0 → 100644
src/components/Form/index.ts
... | ... | @@ -10,5 +10,6 @@ export { default as ApiSelect } from './src/components/ApiSelect.vue'; |
10 | 10 | export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; |
11 | 11 | export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; |
12 | 12 | export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; |
13 | +export { default as ApiCascader } from './src/components/ApiCascader.vue'; | |
13 | 14 | |
14 | 15 | export { BasicForm }; | ... | ... |
src/components/Form/src/componentMap.ts
... | ... | @@ -25,6 +25,7 @@ import ApiRadioGroup from './components/ApiRadioGroup.vue'; |
25 | 25 | import RadioButtonGroup from './components/RadioButtonGroup.vue'; |
26 | 26 | import ApiSelect from './components/ApiSelect.vue'; |
27 | 27 | import ApiTreeSelect from './components/ApiTreeSelect.vue'; |
28 | +import ApiCascader from './components/ApiCascader.vue'; | |
28 | 29 | import { BasicUpload } from '/@/components/Upload'; |
29 | 30 | import { StrengthMeter } from '/@/components/StrengthMeter'; |
30 | 31 | import { IconPicker } from '/@/components/Icon'; |
... | ... | @@ -50,6 +51,7 @@ componentMap.set('RadioButtonGroup', RadioButtonGroup); |
50 | 51 | componentMap.set('RadioGroup', Radio.Group); |
51 | 52 | componentMap.set('Checkbox', Checkbox); |
52 | 53 | componentMap.set('CheckboxGroup', Checkbox.Group); |
54 | +componentMap.set('ApiCascader', ApiCascader); | |
53 | 55 | componentMap.set('Cascader', Cascader); |
54 | 56 | componentMap.set('Slider', Slider); |
55 | 57 | componentMap.set('Rate', Rate); | ... | ... |
src/components/Form/src/components/ApiCascader.vue
0 → 100644
1 | +<template> | |
2 | + <a-cascader | |
3 | + v-model:value="state" | |
4 | + :options="options" | |
5 | + :load-data="loadData" | |
6 | + change-on-select | |
7 | + @change="handleChange" | |
8 | + :displayRender="handleRenderDisplay" | |
9 | + > | |
10 | + <template #suffixIcon v-if="loading"> | |
11 | + <LoadingOutlined spin /> | |
12 | + </template> | |
13 | + <template #notFoundContent v-if="loading"> | |
14 | + <span> | |
15 | + <LoadingOutlined spin class="mr-1" /> | |
16 | + {{ t('component.form.apiSelectNotFound') }} | |
17 | + </span> | |
18 | + </template> | |
19 | + </a-cascader> | |
20 | +</template> | |
21 | +<script lang="ts"> | |
22 | + import { defineComponent, PropType, ref, unref, watch, watchEffect } from 'vue'; | |
23 | + import { Cascader } from 'ant-design-vue'; | |
24 | + import { propTypes } from '/@/utils/propTypes'; | |
25 | + import { isFunction } from '/@/utils/is'; | |
26 | + import { get, omit } from 'lodash-es'; | |
27 | + import { useRuleFormItem } from '/@/hooks/component/useFormItem'; | |
28 | + import { LoadingOutlined } from '@ant-design/icons-vue'; | |
29 | + | |
30 | + interface Option { | |
31 | + value: string; | |
32 | + label: string; | |
33 | + loading?: boolean; | |
34 | + isLeaf?: boolean; | |
35 | + children?: Option[]; | |
36 | + } | |
37 | + export default defineComponent({ | |
38 | + name: 'ApiCascader', | |
39 | + components: { | |
40 | + LoadingOutlined, | |
41 | + [Cascader.name]: Cascader, | |
42 | + }, | |
43 | + props: { | |
44 | + value: { | |
45 | + type: Array, | |
46 | + }, | |
47 | + api: { | |
48 | + type: Function as PropType<(arg?: Recordable) => Promise<Option[]>>, | |
49 | + default: null, | |
50 | + }, | |
51 | + numberToString: propTypes.bool, | |
52 | + resultField: propTypes.string.def(''), | |
53 | + labelField: propTypes.string.def('label'), | |
54 | + valueField: propTypes.string.def('value'), | |
55 | + childrenField: propTypes.string.def('children'), | |
56 | + asyncFetchParamKey: propTypes.string.def('parentCode'), | |
57 | + immediate: propTypes.bool.def(true), | |
58 | + // init fetch params | |
59 | + initFetchParams: { | |
60 | + type: Object as PropType<Recordable>, | |
61 | + default: () => ({}), | |
62 | + }, | |
63 | + // 是否有下级,默认是 | |
64 | + isLeaf: { | |
65 | + type: Function as PropType<(arg: Recordable) => boolean>, | |
66 | + default: null, | |
67 | + }, | |
68 | + displayRenderArray: { | |
69 | + type: Array, | |
70 | + }, | |
71 | + }, | |
72 | + emits: ['change', 'defaultChange'], | |
73 | + setup(props, { emit }) { | |
74 | + const apiData = ref<any[]>([]); | |
75 | + const options = ref<Option[]>([]); | |
76 | + const loading = ref<boolean>(false); | |
77 | + const emitData = ref<any[]>([]); | |
78 | + const isFirstLoad = ref(true); | |
79 | + | |
80 | + // Embedded in the form, just use the hook binding to perform form verification | |
81 | + const [state] = useRuleFormItem(props, 'value', 'change', emitData); | |
82 | + | |
83 | + watch( | |
84 | + apiData, | |
85 | + (data) => { | |
86 | + const opts = generatorOptions(data); | |
87 | + options.value = opts; | |
88 | + }, | |
89 | + { deep: true }, | |
90 | + ); | |
91 | + | |
92 | + function generatorOptions(options: any[]): Option[] { | |
93 | + const { labelField, valueField, numberToString, childrenField, isLeaf } = props; | |
94 | + return options.reduce((prev, next: Recordable) => { | |
95 | + if (next) { | |
96 | + const value = next[valueField]; | |
97 | + const item = { | |
98 | + ...omit(next, [labelField, valueField]), | |
99 | + label: next[labelField], | |
100 | + value: numberToString ? `${value}` : value, | |
101 | + isLeaf: isLeaf && typeof isLeaf === 'function' ? isLeaf(next) : false, | |
102 | + }; | |
103 | + const children = Reflect.get(next, childrenField); | |
104 | + if (children) { | |
105 | + Reflect.set(item, childrenField, generatorOptions(children)); | |
106 | + } | |
107 | + prev.push(item); | |
108 | + } | |
109 | + return prev; | |
110 | + }, [] as Option[]); | |
111 | + } | |
112 | + | |
113 | + async function initialFetch() { | |
114 | + const api = props.api; | |
115 | + if (!api || !isFunction(api)) return; | |
116 | + apiData.value = []; | |
117 | + loading.value = true; | |
118 | + try { | |
119 | + const res = await api(props.initFetchParams); | |
120 | + if (Array.isArray(res)) { | |
121 | + apiData.value = res; | |
122 | + return; | |
123 | + } | |
124 | + if (props.resultField) { | |
125 | + apiData.value = get(res, props.resultField) || []; | |
126 | + } | |
127 | + } catch (error) { | |
128 | + console.warn(error); | |
129 | + } finally { | |
130 | + loading.value = false; | |
131 | + } | |
132 | + } | |
133 | + | |
134 | + async function loadData(selectedOptions: Option[]) { | |
135 | + const targetOption = selectedOptions[selectedOptions.length - 1]; | |
136 | + targetOption.loading = true; | |
137 | + | |
138 | + const api = props.api; | |
139 | + if (!api || !isFunction(api)) return; | |
140 | + try { | |
141 | + const res = await api({ | |
142 | + [props.asyncFetchParamKey]: Reflect.get(targetOption, 'value'), | |
143 | + }); | |
144 | + if (Array.isArray(res)) { | |
145 | + const children = generatorOptions(res); | |
146 | + targetOption.children = children; | |
147 | + return; | |
148 | + } | |
149 | + if (props.resultField) { | |
150 | + const children = generatorOptions(get(res, props.resultField) || []); | |
151 | + targetOption.children = children; | |
152 | + } | |
153 | + } catch (e) { | |
154 | + console.error(e); | |
155 | + } finally { | |
156 | + targetOption.loading = false; | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + watchEffect(() => { | |
161 | + props.immediate && initialFetch(); | |
162 | + }); | |
163 | + | |
164 | + watch( | |
165 | + () => props.initFetchParams, | |
166 | + () => { | |
167 | + !unref(isFirstLoad) && initialFetch(); | |
168 | + }, | |
169 | + { deep: true }, | |
170 | + ); | |
171 | + | |
172 | + function handleChange(keys, args) { | |
173 | + emitData.value = keys; | |
174 | + emit('defaultChange', keys, args); | |
175 | + } | |
176 | + | |
177 | + function handleRenderDisplay({ labels, selectedOptions }) { | |
178 | + if (unref(emitData).length === selectedOptions.length) { | |
179 | + return labels.join(' / '); | |
180 | + } | |
181 | + if (props.displayRenderArray) { | |
182 | + return props.displayRenderArray.join(' / '); | |
183 | + } | |
184 | + return ''; | |
185 | + } | |
186 | + | |
187 | + return { | |
188 | + state, | |
189 | + options, | |
190 | + loading, | |
191 | + handleChange, | |
192 | + loadData, | |
193 | + handleRenderDisplay, | |
194 | + }; | |
195 | + }, | |
196 | + }); | |
197 | +</script> | ... | ... |
src/components/Form/src/types/index.ts
src/views/demo/form/UseForm.vue
... | ... | @@ -52,6 +52,7 @@ |
52 | 52 | > |
53 | 53 | 修改查询按钮 |
54 | 54 | </a-button> |
55 | + <a-button @click="handleLoad" class="mr-2"> 联动回显 </a-button> | |
55 | 56 | </div> |
56 | 57 | <CollapseContainer title="useForm示例"> |
57 | 58 | <BasicForm @register="register" @submit="handleSubmit" /> |
... | ... | @@ -64,6 +65,7 @@ |
64 | 65 | import { CollapseContainer } from '/@/components/Container/index'; |
65 | 66 | import { useMessage } from '/@/hooks/web/useMessage'; |
66 | 67 | import { PageWrapper } from '/@/components/Page'; |
68 | + import { areaRecord } from '/@/api/demo/cascader'; | |
67 | 69 | |
68 | 70 | const schemas: FormSchema[] = [ |
69 | 71 | { |
... | ... | @@ -166,6 +168,48 @@ |
166 | 168 | ], |
167 | 169 | }, |
168 | 170 | }, |
171 | + { | |
172 | + field: 'field8', | |
173 | + component: 'ApiCascader', | |
174 | + label: '联动', | |
175 | + colProps: { | |
176 | + span: 8, | |
177 | + }, | |
178 | + componentProps: { | |
179 | + api: areaRecord, | |
180 | + apiParamKey: 'parentCode', | |
181 | + dataField: 'data', | |
182 | + labelField: 'name', | |
183 | + valueField: 'code', | |
184 | + initFetchParams: { | |
185 | + parentCode: '', | |
186 | + }, | |
187 | + isLeaf: (record) => { | |
188 | + return !(record.levelType < 3); | |
189 | + }, | |
190 | + }, | |
191 | + }, | |
192 | + { | |
193 | + field: 'field9', | |
194 | + component: 'ApiCascader', | |
195 | + label: '联动回显', | |
196 | + colProps: { | |
197 | + span: 8, | |
198 | + }, | |
199 | + componentProps: { | |
200 | + api: areaRecord, | |
201 | + apiParamKey: 'parentCode', | |
202 | + dataField: 'data', | |
203 | + labelField: 'name', | |
204 | + valueField: 'code', | |
205 | + initFetchParams: { | |
206 | + parentCode: '', | |
207 | + }, | |
208 | + isLeaf: (record) => { | |
209 | + return !(record.levelType < 3); | |
210 | + }, | |
211 | + }, | |
212 | + }, | |
169 | 213 | ]; |
170 | 214 | |
171 | 215 | export default defineComponent({ |
... | ... | @@ -173,7 +217,7 @@ |
173 | 217 | setup() { |
174 | 218 | const { createMessage } = useMessage(); |
175 | 219 | |
176 | - const [register, { setProps }] = useForm({ | |
220 | + const [register, { setProps, setFieldsValue, updateSchema }] = useForm({ | |
177 | 221 | labelWidth: 120, |
178 | 222 | schemas, |
179 | 223 | actionColOptions: { |
... | ... | @@ -181,6 +225,35 @@ |
181 | 225 | }, |
182 | 226 | fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']], |
183 | 227 | }); |
228 | + | |
229 | + async function handleLoad() { | |
230 | + const promiseFn = function () { | |
231 | + return new Promise((resolve) => { | |
232 | + setTimeout(() => { | |
233 | + resolve({ | |
234 | + field9: ['430000', '430100', '430102'], | |
235 | + province: '湖南省', | |
236 | + city: '长沙市', | |
237 | + district: '岳麓区', | |
238 | + }); | |
239 | + }, 1000); | |
240 | + }); | |
241 | + }; | |
242 | + | |
243 | + const item = await promiseFn(); | |
244 | + | |
245 | + const { field9, province, city, district } = item as any; | |
246 | + await updateSchema({ | |
247 | + field: 'field9', | |
248 | + componentProps: { | |
249 | + displayRenderArray: [province, city, district], | |
250 | + }, | |
251 | + }); | |
252 | + await setFieldsValue({ | |
253 | + field9, | |
254 | + }); | |
255 | + } | |
256 | + | |
184 | 257 | return { |
185 | 258 | register, |
186 | 259 | schemas, |
... | ... | @@ -188,6 +261,7 @@ |
188 | 261 | createMessage.success('click search,values:' + JSON.stringify(values)); |
189 | 262 | }, |
190 | 263 | setProps, |
264 | + handleLoad, | |
191 | 265 | }; |
192 | 266 | }, |
193 | 267 | }); | ... | ... |