Commit 97fe8e2058147a331442340b209eee596f6033db

Authored by Jobin
Committed by GitHub
1 parent 5c491a42

feat(ApiCascader): add asynchronous cascader component (#1321)

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
  1 +export interface AreaModel {
  2 + id: string;
  3 + code: string;
  4 + parentCode: string;
  5 + name: string;
  6 + levelType: number;
  7 + [key: string]: string | number;
  8 +}
  9 +
  10 +export interface AreaParams {
  11 + parentCode: string;
  12 +}
src/components/Form/index.ts
@@ -10,5 +10,6 @@ export { default as ApiSelect } from &#39;./src/components/ApiSelect.vue&#39;; @@ -10,5 +10,6 @@ export { default as ApiSelect } from &#39;./src/components/ApiSelect.vue&#39;;
10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; 10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; 11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
12 export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'; 12 export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
  13 +export { default as ApiCascader } from './src/components/ApiCascader.vue';
13 14
14 export { BasicForm }; 15 export { BasicForm };
src/components/Form/src/componentMap.ts
@@ -25,6 +25,7 @@ import ApiRadioGroup from &#39;./components/ApiRadioGroup.vue&#39;; @@ -25,6 +25,7 @@ import ApiRadioGroup from &#39;./components/ApiRadioGroup.vue&#39;;
25 import RadioButtonGroup from './components/RadioButtonGroup.vue'; 25 import RadioButtonGroup from './components/RadioButtonGroup.vue';
26 import ApiSelect from './components/ApiSelect.vue'; 26 import ApiSelect from './components/ApiSelect.vue';
27 import ApiTreeSelect from './components/ApiTreeSelect.vue'; 27 import ApiTreeSelect from './components/ApiTreeSelect.vue';
  28 +import ApiCascader from './components/ApiCascader.vue';
28 import { BasicUpload } from '/@/components/Upload'; 29 import { BasicUpload } from '/@/components/Upload';
29 import { StrengthMeter } from '/@/components/StrengthMeter'; 30 import { StrengthMeter } from '/@/components/StrengthMeter';
30 import { IconPicker } from '/@/components/Icon'; 31 import { IconPicker } from '/@/components/Icon';
@@ -50,6 +51,7 @@ componentMap.set(&#39;RadioButtonGroup&#39;, RadioButtonGroup); @@ -50,6 +51,7 @@ componentMap.set(&#39;RadioButtonGroup&#39;, RadioButtonGroup);
50 componentMap.set('RadioGroup', Radio.Group); 51 componentMap.set('RadioGroup', Radio.Group);
51 componentMap.set('Checkbox', Checkbox); 52 componentMap.set('Checkbox', Checkbox);
52 componentMap.set('CheckboxGroup', Checkbox.Group); 53 componentMap.set('CheckboxGroup', Checkbox.Group);
  54 +componentMap.set('ApiCascader', ApiCascader);
53 componentMap.set('Cascader', Cascader); 55 componentMap.set('Cascader', Cascader);
54 componentMap.set('Slider', Slider); 56 componentMap.set('Slider', Slider);
55 componentMap.set('Rate', Rate); 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
@@ -98,6 +98,7 @@ export type ComponentType = @@ -98,6 +98,7 @@ export type ComponentType =
98 | 'Checkbox' 98 | 'Checkbox'
99 | 'CheckboxGroup' 99 | 'CheckboxGroup'
100 | 'AutoComplete' 100 | 'AutoComplete'
  101 + | 'ApiCascader'
101 | 'Cascader' 102 | 'Cascader'
102 | 'DatePicker' 103 | 'DatePicker'
103 | 'MonthPicker' 104 | 'MonthPicker'
src/views/demo/form/UseForm.vue
@@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
52 > 52 >
53 修改查询按钮 53 修改查询按钮
54 </a-button> 54 </a-button>
  55 + <a-button @click="handleLoad" class="mr-2"> 联动回显 </a-button>
55 </div> 56 </div>
56 <CollapseContainer title="useForm示例"> 57 <CollapseContainer title="useForm示例">
57 <BasicForm @register="register" @submit="handleSubmit" /> 58 <BasicForm @register="register" @submit="handleSubmit" />
@@ -64,6 +65,7 @@ @@ -64,6 +65,7 @@
64 import { CollapseContainer } from '/@/components/Container/index'; 65 import { CollapseContainer } from '/@/components/Container/index';
65 import { useMessage } from '/@/hooks/web/useMessage'; 66 import { useMessage } from '/@/hooks/web/useMessage';
66 import { PageWrapper } from '/@/components/Page'; 67 import { PageWrapper } from '/@/components/Page';
  68 + import { areaRecord } from '/@/api/demo/cascader';
67 69
68 const schemas: FormSchema[] = [ 70 const schemas: FormSchema[] = [
69 { 71 {
@@ -166,6 +168,48 @@ @@ -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 export default defineComponent({ 215 export default defineComponent({
@@ -173,7 +217,7 @@ @@ -173,7 +217,7 @@
173 setup() { 217 setup() {
174 const { createMessage } = useMessage(); 218 const { createMessage } = useMessage();
175 219
176 - const [register, { setProps }] = useForm({ 220 + const [register, { setProps, setFieldsValue, updateSchema }] = useForm({
177 labelWidth: 120, 221 labelWidth: 120,
178 schemas, 222 schemas,
179 actionColOptions: { 223 actionColOptions: {
@@ -181,6 +225,35 @@ @@ -181,6 +225,35 @@
181 }, 225 },
182 fieldMapToTime: [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM']], 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 return { 257 return {
185 register, 258 register,
186 schemas, 259 schemas,
@@ -188,6 +261,7 @@ @@ -188,6 +261,7 @@
188 createMessage.success('click search,values:' + JSON.stringify(values)); 261 createMessage.success('click search,values:' + JSON.stringify(values));
189 }, 262 },
190 setProps, 263 setProps,
  264 + handleLoad,
191 }; 265 };
192 }, 266 },
193 }); 267 });