Commit 9bf9339a1103287024dd365d8a6980450ff7f65b

Authored by zhangdaiscott
1 parent 07812d51

JVXETable提供三级联动简单方案,解决联动展示与选择BUG #2867

ant-design-vue-jeecg/src/components/jeecg/JVxeTable/components/JVxeTable.js
... ... @@ -98,6 +98,8 @@ export default {
98 98 // 是否一直显示组件,如果为false则只有点击的时候才出现组件
99 99 // 注:该参数不能动态修改;如果行、列字段多的情况下,会根据机器性能造成不同程度的卡顿。
100 100 alwaysEdit: PropTypes.bool.def(false),
  101 + // 联动配置,数组,详情配置见文档
  102 + linkageConfig: PropTypes.array.def(() => []),
101 103 },
102 104 data() {
103 105 return {
... ... @@ -151,7 +153,10 @@ export default {
151 153 // 允许执行刷新特效的行ID
152 154 reloadEffectRowKeysMap: {},
153 155 //配置了但是没有授权的按钮和列 集合
154   - excludeCode:[]
  156 + excludeCode:[],
  157 + // 联动下拉选项(用于隔离不同的下拉选项)
  158 + // 内部联动配置,map
  159 + _innerLinkageConfig: null,
155 160 }
156 161 },
157 162 computed: {
... ... @@ -178,6 +183,18 @@ export default {
178 183 renderOptions.target = this
179 184 }
180 185 }
  186 + // 处理联动列,联动列只能作用于 select 组件
  187 + if (column.$type === JVXETypes.select && this._innerLinkageConfig != null) {
  188 + // 判断当前列是否是联动列
  189 + if (this._innerLinkageConfig.has(column.key)) {
  190 + renderOptions.linkage = {
  191 + config: this._innerLinkageConfig.get(column.key),
  192 + getLinkageOptionsSibling: this.getLinkageOptionsSibling,
  193 + getLinkageOptionsAsync: this.getLinkageOptionsAsync,
  194 + linkageSelectChange: this.linkageSelectChange,
  195 + }
  196 + }
  197 + }
181 198 if (column.editRender) {
182 199 Object.assign(column.editRender, renderOptions)
183 200 }
... ... @@ -278,15 +295,21 @@ export default {
278 295 immediate: true,
279 296 async handler() {
280 297 let vxe = await getRefPromise(this, 'vxe')
281   - // 阻断vue监听大数据,提高性能
282 298  
283   - // 开启了排序就自动计算排序值
284   - if (this.dragSort) {
285   - this.dataSource.forEach((data, idx) => {
  299 + this.dataSource.forEach((data, idx) => {
  300 + // 开启了排序就自动计算排序值
  301 + if (this.dragSort) {
286 302 this.$set(data, this.dragSortKey, idx + 1)
287   - })
288   - }
  303 + }
  304 + // 处理联动回显数据
  305 + if (this._innerLinkageConfig != null) {
  306 + for (let configItem of this._innerLinkageConfig.values()) {
  307 + this.autoSetLinkageOptionsByData(data, '', configItem, 0)
  308 + }
  309 + }
  310 + })
289 311  
  312 + // 阻断vue监听大数据,提高性能
290 313 vxe.loadData(this.dataSource)
291 314  
292 315 // TODO 解析disabledRows
... ... @@ -469,7 +492,40 @@ export default {
469 492 this._innerColumns = _innerColumns
470 493 this._innerEditRules = _innerEditRules
471 494 }
472   - }
  495 + },
  496 + // watch linkageConfig
  497 + // 整理多级联动配置
  498 + linkageConfig: {
  499 + immediate: true,
  500 + handler() {
  501 + if (Array.isArray(this.linkageConfig) && this.linkageConfig.length > 0) {
  502 + // 获取联动的key顺序
  503 + let getLcKeys = (key, arr) => {
  504 + let col = this._innerColumns.find(col => col.key === key)
  505 + if (col) {
  506 + arr.push(col.key)
  507 + if (col.linkageKey) {
  508 + return getLcKeys(col.linkageKey, arr)
  509 + }
  510 + }
  511 + return arr
  512 + }
  513 + let configMap = new Map()
  514 + this.linkageConfig.forEach(lc => {
  515 + let keys = getLcKeys(lc.key, [])
  516 + // 多个key共享一个,引用地址
  517 + let configItem = {
  518 + ...lc, keys,
  519 + optionsMap: new Map()
  520 + }
  521 + keys.forEach(k => configMap.set(k, configItem))
  522 + })
  523 + this._innerLinkageConfig = configMap
  524 + } else {
  525 + this._innerLinkageConfig = null
  526 + }
  527 + }
  528 + },
473 529 },
474 530 created() {
475 531 },
... ... @@ -671,6 +727,19 @@ export default {
671 727 // issues/2784
672 728 // 先清空所有数据
673 729 xTable.loadData([])
  730 +
  731 + dataSource.forEach((data, idx) => {
  732 + // 开启了排序就自动计算排序值
  733 + if (this.dragSort) {
  734 + this.$set(data, this.dragSortKey, idx + 1)
  735 + }
  736 + // 处理联动回显数据
  737 + if (this._innerLinkageConfig != null) {
  738 + for (let configItem of this._innerLinkageConfig.values()) {
  739 + this.autoSetLinkageOptionsByData(data, '', configItem, 0)
  740 + }
  741 + }
  742 + })
674 743 // 再新增
675 744 return xTable.insertAt(dataSource)
676 745 }
... ... @@ -797,6 +866,7 @@ export default {
797 866 * 添加一行或多行
798 867 *
799 868 * @param rows
  869 + * @param isOnlJs 是否是onlineJS增强触发的
800 870 * @return
801 871 */
802 872 async addRows(rows = {}, isOnlJs) {
... ... @@ -896,6 +966,89 @@ export default {
896 966 this.$emit(name, event)
897 967 },
898 968  
  969 + /** 【多级联动】获取同级联动下拉选项 */
  970 + getLinkageOptionsSibling(row, col, config, request) {
  971 + // 如果当前列不是顶级列
  972 + let key = ''
  973 + if (col.key !== config.key) {
  974 + // 就找出联动上级列
  975 + let idx = config.keys.findIndex(k => col.key === k)
  976 + let parentKey = config.keys[idx - 1]
  977 + key = row[parentKey]
  978 + // 如果联动上级列没有选择数据,就直接返回空数组
  979 + if (key === '' || key == null) {
  980 + return []
  981 + }
  982 + } else {
  983 + key = 'root'
  984 + }
  985 + let options = config.optionsMap.get(key)
  986 + if (!Array.isArray(options)) {
  987 + if (request) {
  988 + let parent = key === 'root' ? '' : key
  989 + return this.getLinkageOptionsAsync(config, parent)
  990 + } else {
  991 + options = []
  992 + }
  993 + }
  994 + return options
  995 + },
  996 + /** 【多级联动】获取联动下拉选项(异步) */
  997 + getLinkageOptionsAsync(config, parent) {
  998 + return new Promise(resolve => {
  999 + let key = parent ? parent : 'root'
  1000 + let options
  1001 + if (config.optionsMap.has(key)) {
  1002 + options = config.optionsMap.get(key)
  1003 + if (options instanceof Promise) {
  1004 + options.then(opt => {
  1005 + config.optionsMap.set(key, opt)
  1006 + resolve(opt)
  1007 + })
  1008 + } else {
  1009 + resolve(options)
  1010 + }
  1011 + } else if (typeof config.requestData === 'function') {
  1012 + // 调用requestData方法,通过传入parent来获取子级
  1013 + let promise = config.requestData(parent)
  1014 + config.optionsMap.set(key, promise)
  1015 + promise.then(opt => {
  1016 + config.optionsMap.set(key, opt)
  1017 + resolve(opt)
  1018 + })
  1019 + } else {
  1020 + resolve([])
  1021 + }
  1022 + })
  1023 + },
  1024 + // 【多级联动】 用于回显数据,自动填充 optionsMap
  1025 + autoSetLinkageOptionsByData(data, parent, config, level) {
  1026 + if (level === 0) {
  1027 + this.getLinkageOptionsAsync(config, '')
  1028 + } else {
  1029 + this.getLinkageOptionsAsync(config, parent)
  1030 + }
  1031 + if (config.keys.length - 1 > level) {
  1032 + let value = data[config.keys[level]]
  1033 + if (value) {
  1034 + this.autoSetLinkageOptionsByData(data, value, config, level + 1)
  1035 + }
  1036 + }
  1037 + },
  1038 + // 【多级联动】联动组件change时,清空下级组件
  1039 + linkageSelectChange(row, col, config, value) {
  1040 + if (col.linkageKey) {
  1041 + this.getLinkageOptionsAsync(config, value)
  1042 + let idx = config.keys.findIndex(k => k === col.key)
  1043 + let values = {}
  1044 + for (let i = idx; i < config.keys.length; i++) {
  1045 + values[config.keys[i]] = ''
  1046 + }
  1047 + // 清空后几列的数据
  1048 + this.setValues([{rowKey: row.id, values}])
  1049 + }
  1050 + },
  1051 +
899 1052 /** 加载数据字典并合并到 options */
900 1053 _loadDictConcatToOptions(column) {
901 1054 initDictOptions(column.dictCode).then((res) => {
... ... @@ -1088,6 +1241,15 @@ export default {
1088 1241 let createValue = getEnhancedMixins(col.$type || col.type, 'createValue')
1089 1242 record[col.key] = createValue({row: record, column, $table: xTable})
1090 1243 }
  1244 + // update-begin--author:sunjianlei---date:20210819------for: 处理联动列,联动列只能作用于 select 组件
  1245 + if (col.$type === JVXETypes.select && this._innerLinkageConfig != null) {
  1246 + // 判断当前列是否是联动列
  1247 + if (this._innerLinkageConfig.has(col.key)) {
  1248 + let configItem = this._innerLinkageConfig.get(col.key)
  1249 + this.getLinkageOptionsAsync(configItem, '')
  1250 + }
  1251 + }
  1252 + // update-end--author:sunjianlei---date:20210819------for: 处理联动列,联动列只能作用于 select 组件
1091 1253 })
1092 1254 return record
1093 1255 },
... ...
ant-design-vue-jeecg/src/components/jeecg/JVxeTable/components/cells/JVxeSelectCell.vue
... ... @@ -7,11 +7,16 @@
7 7 v-bind="selectProps"
8 8 style="width: 100%;"
9 9 @blur="handleBlur"
10   - @change="handleChangeCommon"
  10 + @change="handleChange"
11 11 @search="handleSearchSelect"
12 12 >
13 13  
14   - <template v-for="option of originColumn.options">
  14 + <div v-if="loading" slot="notFoundContent">
  15 + <a-icon type="loading" />
  16 + <span>&nbsp;加载中…</span>
  17 + </div>
  18 +
  19 + <template v-for="option of selectOptions">
15 20 <a-select-option :key="option.value" :value="option.value" :disabled="option.disabled">
16 21 <span>{{option.text || option.label || option.title|| option.value}}</span>
17 22 </a-select-option>
... ... @@ -23,10 +28,18 @@
23 28 <script>
24 29 import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
25 30 import { JVXETypes } from '@comp/jeecg/JVxeTable/index'
  31 + import { filterDictText } from '@comp/dict/JDictSelectUtil'
26 32  
27 33 export default {
28 34 name: 'JVxeSelectCell',
29 35 mixins: [JVxeCellMixins],
  36 + data(){
  37 + return {
  38 + loading: false,
  39 + // 异步加载的options(用于多级联动)
  40 + asyncOptions: null,
  41 + }
  42 + },
30 43 computed: {
31 44 selectProps() {
32 45 let props = {...this.cellProps}
... ... @@ -37,6 +50,32 @@
37 50 }
38 51 return props
39 52 },
  53 + // 下拉选项
  54 + selectOptions() {
  55 + if (this.asyncOptions) {
  56 + return this.asyncOptions
  57 + }
  58 + let {linkage} = this.renderOptions
  59 + if (linkage) {
  60 + let {getLinkageOptionsSibling, config} = linkage
  61 + let res = getLinkageOptionsSibling(this.row, this.originColumn, config, true)
  62 + // 当返回Promise时,说明是多级联动
  63 + if (res instanceof Promise) {
  64 + this.loading = true
  65 + res.then(opt => {
  66 + this.asyncOptions = opt
  67 + this.loading = false
  68 + }).catch(e => {
  69 + console.error(e)
  70 + this.loading = false
  71 + })
  72 + } else {
  73 + this.asyncOptions = null
  74 + return res
  75 + }
  76 + }
  77 + return this.originColumn.options
  78 + },
40 79 },
41 80 created() {
42 81 let multiple = [JVXETypes.selectMultiple, JVXETypes.list_multi]
... ... @@ -54,6 +93,16 @@
54 93 },
55 94 methods: {
56 95  
  96 + handleChange(value) {
  97 + debugger
  98 + // 处理下级联动
  99 + let linkage = this.renderOptions.linkage
  100 + if (linkage) {
  101 + linkage.linkageSelectChange(this.row, this.originColumn, linkage.config, value)
  102 + }
  103 + this.handleChangeCommon(value)
  104 + },
  105 +
57 106 /** 处理blur失去焦点事件 */
58 107 handleBlur(value) {
59 108 let {allowInput, options} = this.originColumn
... ... @@ -120,7 +169,28 @@
120 169 dispatchEvent.call(this, event, 'ant-select')
121 170 },
122 171 },
123   - translate: {enabled: true},
  172 + translate: {
  173 + enabled: true,
  174 + async handler(value,) {
  175 + let options
  176 + let {linkage} = this.renderOptions
  177 + // 判断是否是多级联动,如果是就通过接口异步翻译
  178 + if (linkage) {
  179 + let {getLinkageOptionsSibling, config} = linkage
  180 + options = getLinkageOptionsSibling(this.row, this.originColumn, config, true)
  181 + if (options instanceof Promise) {
  182 + return new Promise(resolve => {
  183 + options.then(opt => {
  184 + resolve(filterDictText(opt, value))
  185 + })
  186 + })
  187 + }
  188 + } else {
  189 + options = this.column.own.options
  190 + }
  191 + return filterDictText(options, value)
  192 + },
  193 + },
124 194 getValue(value) {
125 195 if (Array.isArray(value)) {
126 196 return value.join(',')
... ...
ant-design-vue-jeecg/src/components/jeecg/JVxeTable/mixins/JVxeCellMixins.js
... ... @@ -102,7 +102,13 @@ export default {
102 102  
103 103 // 判断是否启用翻译
104 104 if (this.renderType === JVXERenderType.spaner && this.enhanced.translate.enabled) {
105   - this.innerValue = this.enhanced.translate.handler.call(this, value)
  105 + let res = this.enhanced.translate.handler.call(this, value)
  106 + // 异步翻译,目前仅【多级联动】使用
  107 + if (res instanceof Promise) {
  108 + res.then(value => this.innerValue = value)
  109 + } else {
  110 + this.innerValue = res
  111 + }
106 112 }
107 113 },
108 114 },
... ...
ant-design-vue-jeecg/src/views/jeecg/JVxeDemo/JVxeDemo3.vue
... ... @@ -8,123 +8,173 @@
8 8 :height="484"
9 9 :dataSource="dataSource"
10 10 :columns="columns"
11   - @valueChange="handleValueChange"
  11 + :linkage-config="linkageConfig"
12 12 />
13 13 </template>
14 14  
15 15 <script>
16   - import moment from 'moment'
17   - import { randomNumber, randomUUID } from '@/utils/util'
18   - import { JVXETypes } from '@/components/jeecg/JVxeTable'
  16 +import { JVXETypes } from '@/components/jeecg/JVxeTable'
19 17  
20   - export default {
21   - name: 'JVxeDemo2',
22   - data() {
23   - return {
24   - columns: [
25   - {
26   - title: '省/直辖市/自治区',
27   - key: 's1',
28   - type: JVXETypes.select,
29   - width: '240px',
30   - options: [],
31   - placeholder: '请选择${title}'
32   - },
33   - {
34   - title: '市',
35   - key: 's2',
36   - type: JVXETypes.select,
37   - width: '240px',
38   - options: [],
39   - placeholder: '请选择${title}'
40   - },
41   - {
42   - title: '县/区',
43   - key: 's3',
44   - type: JVXETypes.select,
45   - width: '240px',
46   - options: [],
47   - placeholder: '请选择${title}'
48   - }
49   - ],
50   - dataSource: [],
51   -
52   - mockData: [
53   - { text: '北京市', value: '110000', parent: null },
54   - { text: '天津市', value: '120000', parent: null },
55   - { text: '河北省', value: '130000', parent: null },
56   - { text: '上海市', value: '310000', parent: null },
57   -
58   - { text: '北京市', value: '110100', parent: '110000' },
59   - { text: '天津市市', value: '120100', parent: '120000' },
60   - { text: '石家庄市', value: '130100', parent: '130000' },
61   - { text: '唐山市', value: '130200', parent: '130000' },
62   - { text: '秦皇岛市', value: '130300', parent: '130000' },
63   - { text: '上海市', value: '310100', parent: '310000' },
64   -
65   - { text: '东城区', value: '110101', parent: '110100' },
66   - { text: '西城区', value: '110102', parent: '110100' },
67   - { text: '朝阳区', value: '110105', parent: '110100' },
68   - { text: '和平区', value: '120101', parent: '120100' },
69   - { text: '河东区', value: '120102', parent: '120100' },
70   - { text: '河西区', value: '120103', parent: '120100' },
71   - { text: '黄浦区', value: '310101', parent: '310100' },
72   - { text: '徐汇区', value: '310104', parent: '310100' },
73   - { text: '长宁区', value: '310105', parent: '310100' },
74   - { text: '长安区', value: '130102', parent: '130100' },
75   - { text: '桥西区', value: '130104', parent: '130100' },
76   - { text: '新华区', value: '130105', parent: '130100' },
77   - { text: '路南区', value: '130202', parent: '130200' },
78   - { text: '路北区', value: '130203', parent: '130200' },
79   - { text: '古冶区', value: '130204', parent: '130200' },
80   - { text: '海港区', value: '130302', parent: '130300' },
81   - { text: '山海关区', value: '130303', parent: '130300' },
82   - { text: '北戴河区', value: '130304', parent: '130300' },
83   - ]
84   - }
  18 +export default {
  19 + name: 'JVxeDemo2',
  20 + data() {
  21 + return {
  22 + // 联动配置
  23 + linkageConfig: [
  24 + {requestData: this.requestData, key: 's1'},
  25 + // 可配置多个联动
  26 + {requestData: this.loadData, key: 'level1',},
  27 + ],
  28 + columns: [
  29 + {
  30 + title: '性别',
  31 + key: 'sex',
  32 + type: JVXETypes.select,
  33 + dictCode: 'sex',
  34 + width: '180px',
  35 + placeholder: '请选择${title}',
  36 + },
  37 + {
  38 + title: '省/直辖市/自治区',
  39 + key: 's1',
  40 + type: JVXETypes.select,
  41 + width: '180px',
  42 + placeholder: '请选择${title}',
  43 + // 联动字段(即下一级的字段)
  44 + linkageKey: 's2',
  45 + },
  46 + {
  47 + title: '市',
  48 + key: 's2',
  49 + type: JVXETypes.select,
  50 + width: '180px',
  51 + placeholder: '请选择${title}',
  52 + // 联动字段(即下一级的字段)
  53 + linkageKey: 's3',
  54 + },
  55 + {
  56 + title: '县/区',
  57 + key: 's3',
  58 + type: JVXETypes.select,
  59 + width: '180px',
  60 + options: [],
  61 + placeholder: '请选择${title}',
  62 + },
  63 + {
  64 + title: '一级',
  65 + key: 'level1',
  66 + type: JVXETypes.select,
  67 + width: '180px',
  68 + placeholder: '请选择${title}',
  69 + // 联动字段(即下一级的字段)
  70 + linkageKey: 'level2',
  71 + },
  72 + {
  73 + title: '二级',
  74 + key: 'level2',
  75 + type: JVXETypes.select,
  76 + width: '180px',
  77 + placeholder: '请选择${title}',
  78 + // 联动字段(即下一级的字段)
  79 + linkageKey: 'level3',
  80 + },
  81 + {
  82 + title: '三级',
  83 + key: 'level3',
  84 + type: JVXETypes.select,
  85 + width: '180px',
  86 + placeholder: '请选择${title}',
  87 + }
  88 + ],
  89 + dataSource: [
  90 + {sex: '1', s1: '110000', s2: '110100', s3: '110101', level1: '1', level2: '3', level3: '7'},
  91 + {sex: '2', s1: '130000', s2: '130300', s3: '130303', level1: '2', level2: '6', level3: '14'},
  92 + ],
  93 + // 模拟数据
  94 + mockData: [
  95 + {text: '北京市', value: '110000', parent: ''},
  96 + {text: '天津市', value: '120000', parent: ''},
  97 + {text: '河北省', value: '130000', parent: ''},
  98 + {text: '上海市', value: '310000', parent: ''},
85 99  
  100 + {text: '北京市', value: '110100', parent: '110000'},
  101 + {text: '天津市市', value: '120100', parent: '120000'},
  102 + {text: '石家庄市', value: '130100', parent: '130000'},
  103 + {text: '唐山市', value: '130200', parent: '130000'},
  104 + {text: '秦皇岛市', value: '130300', parent: '130000'},
  105 + {text: '上海市', value: '310100', parent: '310000'},
  106 +
  107 + {text: '东城区', value: '110101', parent: '110100'},
  108 + {text: '西城区', value: '110102', parent: '110100'},
  109 + {text: '朝阳区', value: '110105', parent: '110100'},
  110 + {text: '和平区', value: '120101', parent: '120100'},
  111 + {text: '河东区', value: '120102', parent: '120100'},
  112 + {text: '河西区', value: '120103', parent: '120100'},
  113 + {text: '黄浦区', value: '310101', parent: '310100'},
  114 + {text: '徐汇区', value: '310104', parent: '310100'},
  115 + {text: '长宁区', value: '310105', parent: '310100'},
  116 + {text: '长安区', value: '130102', parent: '130100'},
  117 + {text: '桥西区', value: '130104', parent: '130100'},
  118 + {text: '新华区', value: '130105', parent: '130100'},
  119 + {text: '路南区', value: '130202', parent: '130200'},
  120 + {text: '路北区', value: '130203', parent: '130200'},
  121 + {text: '古冶区', value: '130204', parent: '130200'},
  122 + {text: '海港区', value: '130302', parent: '130300'},
  123 + {text: '山海关区', value: '130303', parent: '130300'},
  124 + {text: '北戴河区', value: '130304', parent: '130300'},
  125 + ],
  126 + mockData1: [
  127 + {id: '1', name: '图书馆', parentId: '0'},
  128 + {id: '2', name: '电影院', parentId: '0'},
  129 +
  130 + {id: '3', name: '一楼', parentId: '1'},
  131 + {id: '4', name: '二楼', parentId: '1'},
  132 + {id: '5', name: '中影星美', parentId: '2'},
  133 + {id: '6', name: '万达国际', parentId: '2'},
  134 +
  135 + {id: '7', name: '技术图书', parentId: '3'},
  136 + {id: '8', name: '财务图书', parentId: '3'},
  137 + {id: '9', name: '儿童图书', parentId: '4'},
  138 + {id: '10', name: '励志图书', parentId: '4'},
  139 + {id: '11', name: '1号厅', parentId: '5'},
  140 + {id: '12', name: '2号厅', parentId: '5'},
  141 + {id: '13', name: 'I-MAX厅', parentId: '6'},
  142 + {id: '14', name: '3D厅', parentId: '6'},
  143 + ],
  144 + }
  145 + },
  146 + methods: {
  147 + /**
  148 + * 模拟从后台查询数据
  149 + */
  150 + requestData(parent) {
  151 + return new Promise((resolve, reject) => {
  152 + let data = this.mockData.filter(i => i.parent === parent)
  153 + setTimeout(() => {
  154 + resolve(data)
  155 + }, 500)
  156 + })
86 157 },
87   - created() {
88   - // 初始化数据
89   - this.columns[0].options = this.request(null)
90   - },
91   - methods: {
92   -
93   - request(parentId) {
94   - return this.mockData.filter(i => i.parent === parentId)
95   - },
96   -
97   - /** 当选项被改变时,联动其他组件 */
98   - handleValueChange(event) {
99   - const { type, row, column, value, target } = event
100   - console.log("event",event)
101   - if (type === JVXETypes.select) {
102   -
103   - // 第一列
104   - if (column.key === 's1') {
105   - // 设置第二列的 options
106   - console.log('this.request(value)::',this.request(value))
107   - target.$refs.vxe.columns[3].options = this.request(value)
108   - // 清空后两列的数据
109   - target.setValues([{
110   - rowKey: row.id,
111   - values: { s2: '', s3: '' }
112   - }])
113   - target.$refs.vxe.columns[4].options = []
114   - } else
115   - // 第二列
116   - if (column.key === 's2') {
117   - target.$refs.vxe.columns[4].options = this.request(value)
118   - target.setValues([{
119   - rowKey: row.id,
120   - values: { s3: '' }
121   - }])
  158 +
  159 + // 模拟加载数据,模拟数据格式不同的情况下如何组装数据
  160 + async loadData(parent) {
  161 + return new Promise((resolve, reject) => {
  162 + let parentId = parent === '' ? '0' : parent
  163 + let data = this.mockData1.filter(i => i.parentId === parentId)
  164 + data = data.map(item => {
  165 + return {
  166 + // 必须包含以下两个字段
  167 + value: item.id,
  168 + text: item.name,
122 169 }
123   - }
124   -
125   - }
126   - }
  170 + })
  171 + setTimeout(() => {
  172 + resolve(data)
  173 + }, 500)
  174 + })
  175 + },
127 176 }
  177 +}
128 178 </script>
129 179  
130 180 <style scoped>
... ...