vxe-table 3.7.0-beta.8 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +1 -1
  2. package/helper/vetur/attributes.json +26 -2
  3. package/helper/vetur/tags.json +6 -0
  4. package/lib/button/style/style.css +2 -3
  5. package/lib/button/style/style.min.css +1 -1
  6. package/lib/edit/src/mixin.js +267 -215
  7. package/lib/edit/src/mixin.min.js +1 -1
  8. package/lib/export/src/mixin.js +11 -7
  9. package/lib/export/src/mixin.min.js +1 -1
  10. package/lib/form/src/form-config-item.js +5 -1
  11. package/lib/form/src/form-config-item.min.js +1 -1
  12. package/lib/form/src/form-item.js +9 -1
  13. package/lib/form/src/form-item.min.js +1 -1
  14. package/lib/form/src/form.js +4 -0
  15. package/lib/form/src/form.min.js +1 -1
  16. package/lib/form/style/style.css +12 -0
  17. package/lib/form/style/style.min.css +1 -1
  18. package/lib/icon/style/style.css +1 -1
  19. package/lib/icon/style/style.min.css +1 -1
  20. package/lib/index.css +1 -1
  21. package/lib/index.umd.js +1155 -723
  22. package/lib/index.umd.min.js +1 -1
  23. package/lib/input/src/input.js +24 -1
  24. package/lib/input/src/input.min.js +1 -1
  25. package/lib/input/style/style.css +21 -0
  26. package/lib/input/style/style.min.css +1 -1
  27. package/lib/keyboard/src/mixin.js +4 -1
  28. package/lib/keyboard/src/mixin.min.js +1 -1
  29. package/lib/style.css +1 -1
  30. package/lib/style.min.css +1 -1
  31. package/lib/table/src/body.js +18 -15
  32. package/lib/table/src/body.min.js +1 -1
  33. package/lib/table/src/cell.js +38 -32
  34. package/lib/table/src/cell.min.js +1 -1
  35. package/lib/table/src/columnInfo.js +3 -3
  36. package/lib/table/src/columnInfo.min.js +1 -1
  37. package/lib/table/src/methods.js +652 -426
  38. package/lib/table/src/methods.min.js +1 -1
  39. package/lib/table/src/table.js +38 -24
  40. package/lib/table/src/table.min.js +1 -1
  41. package/lib/table/src/util.js +4 -2
  42. package/lib/table/src/util.min.js +1 -1
  43. package/lib/table/style/style.css +7 -2
  44. package/lib/table/style/style.min.css +1 -1
  45. package/lib/toolbar/src/toolbar.js +5 -1
  46. package/lib/toolbar/src/toolbar.min.js +1 -1
  47. package/lib/tools/log.js +1 -1
  48. package/lib/tools/log.min.js +1 -1
  49. package/lib/tools/utils.js +3 -5
  50. package/lib/tools/utils.min.js +1 -1
  51. package/lib/tooltip/style/style.css +0 -6
  52. package/lib/tooltip/style/style.min.css +1 -1
  53. package/lib/v-x-e-table/index.js +15 -12
  54. package/lib/v-x-e-table/index.min.js +1 -1
  55. package/lib/v-x-e-table/src/commands.js +3 -1
  56. package/lib/v-x-e-table/src/conf.js +5 -5
  57. package/lib/v-x-e-table/src/conf.min.js +1 -1
  58. package/lib/v-x-e-table/src/{setup.js → config.js} +3 -3
  59. package/lib/v-x-e-table/src/config.min.js +1 -0
  60. package/lib/v-x-e-table/src/formats.js +4 -2
  61. package/lib/v-x-e-table/src/formats.min.js +1 -1
  62. package/lib/v-x-e-table/src/menus.js +3 -1
  63. package/lib/v-x-e-table/src/renderer.js +4 -4
  64. package/lib/v-x-e-table/src/renderer.min.js +1 -1
  65. package/lib/validator/src/mixin.js +14 -1
  66. package/lib/validator/src/mixin.min.js +1 -1
  67. package/package.json +7 -8
  68. package/packages/edit/src/mixin.js +186 -143
  69. package/packages/export/src/mixin.js +9 -7
  70. package/packages/form/src/form-config-item.js +4 -2
  71. package/packages/form/src/form-item.js +8 -2
  72. package/packages/form/src/form.js +4 -0
  73. package/packages/input/src/input.js +24 -1
  74. package/packages/keyboard/src/mixin.js +2 -1
  75. package/packages/table/src/body.js +18 -15
  76. package/packages/table/src/cell.js +32 -23
  77. package/packages/table/src/columnInfo.js +3 -3
  78. package/packages/table/src/methods.js +485 -239
  79. package/packages/table/src/table.js +36 -22
  80. package/packages/table/src/util.js +4 -2
  81. package/packages/toolbar/src/toolbar.js +4 -1
  82. package/packages/tools/utils.js +3 -6
  83. package/packages/v-x-e-table/index.js +7 -4
  84. package/packages/v-x-e-table/src/commands.js +3 -1
  85. package/packages/v-x-e-table/src/conf.js +5 -5
  86. package/packages/v-x-e-table/src/{setup.js → config.js} +2 -2
  87. package/packages/v-x-e-table/src/formats.js +4 -2
  88. package/packages/v-x-e-table/src/menus.js +3 -1
  89. package/packages/v-x-e-table/src/renderer.js +4 -4
  90. package/packages/validator/src/mixin.js +12 -1
  91. package/styles/button.scss +5 -3
  92. package/styles/css-variable.scss +3 -3
  93. package/styles/form.scss +14 -0
  94. package/styles/input.scss +25 -0
  95. package/styles/table.scss +13 -2
  96. package/styles/textarea.scss +3 -3
  97. package/styles/tooltip.scss +0 -8
  98. package/styles/variable.scss +3 -3
  99. package/types/all.d.ts +2 -2
  100. package/types/form-item.d.ts +1 -0
  101. package/types/form.d.ts +1 -0
  102. package/types/table.d.ts +36 -5
  103. package/types/v-x-e-table/config.d.ts +51 -0
  104. package/types/v-x-e-table/formats.d.ts +1 -1
  105. package/types/v-x-e-table/index.d.ts +22 -10
  106. package/lib/v-x-e-table/src/setup.min.js +0 -1
  107. package/types/v-x-e-table/setup.d.ts +0 -74
  108. /package/lib/icon/style/{iconfont.1690504677290.ttf → iconfont.1694737793729.ttf} +0 -0
  109. /package/lib/icon/style/{iconfont.1690504677290.woff → iconfont.1694737793729.woff} +0 -0
  110. /package/lib/icon/style/{iconfont.1690504677290.woff2 → iconfont.1694737793729.woff2} +0 -0
  111. /package/lib/{iconfont.1690504677290.ttf → iconfont.1694737793729.ttf} +0 -0
  112. /package/lib/{iconfont.1690504677290.woff → iconfont.1694737793729.woff} +0 -0
  113. /package/lib/{iconfont.1690504677290.woff2 → iconfont.1694737793729.woff2} +0 -0
@@ -52,9 +52,15 @@ function getCustomStorageMap (key) {
52
52
  return rest && rest._v === version ? rest : { _v: version }
53
53
  }
54
54
 
55
- function getRecoverRow (_vm, list) {
56
- const { fullAllDataRowMap } = _vm
57
- return list.filter(row => fullAllDataRowMap.has(row))
55
+ const getRecoverRowMaps = (_vm, keyMaps) => {
56
+ const { fullAllDataRowIdData } = _vm
57
+ const restKeys = {}
58
+ XEUtils.each(keyMaps, (row, rowid) => {
59
+ if (fullAllDataRowIdData[rowid]) {
60
+ restKeys[rowid] = row
61
+ }
62
+ })
63
+ return restKeys
58
64
  }
59
65
 
60
66
  function handleReserveRow (_vm, reserveRowMap) {
@@ -357,6 +363,7 @@ const Methods = {
357
363
  */
358
364
  loadTableData (datas) {
359
365
  const { keepSource, treeConfig, treeOpts, editStore, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop, scrollYLoad: oldScrollYLoad, sXOpts, sYOpts } = this
366
+ const childrenField = treeOpts.children || treeOpts.childrenField
360
367
  let treeData = []
361
368
  let fullData = datas ? datas.slice(0) : []
362
369
  if (treeConfig) {
@@ -369,26 +376,26 @@ const Methods = {
369
376
  if (!treeOpts.parentField) {
370
377
  errLog('vxe.error.reqProp', ['table.tree-config.parentField'])
371
378
  }
372
- if (!treeOpts.children) {
373
- errLog('vxe.error.reqProp', ['tree-config.children'])
379
+ if (!childrenField) {
380
+ errLog('vxe.error.reqProp', ['tree-config.childrenField'])
374
381
  }
375
- if (!treeOpts.mapChildren) {
376
- errLog('vxe.error.reqProp', ['tree-config.mapChildren'])
382
+ if (!treeOpts.mapChildrenField) {
383
+ errLog('vxe.error.reqProp', ['tree-config.mapChildrenField'])
377
384
  }
378
- if (treeOpts.children === treeOpts.mapChildren) {
379
- errLog('vxe.error.errConflicts', ['tree-config.children', 'tree-config.mapChildren'])
385
+ if (childrenField === treeOpts.mapChildrenField) {
386
+ errLog('vxe.error.errConflicts', ['tree-config.childrenField', 'tree-config.mapChildrenField'])
380
387
  }
381
388
  fullData.forEach(row => {
382
- if (row[treeOpts.children] && row[treeOpts.children].length) {
383
- warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
389
+ if (row[childrenField] && row[childrenField].length) {
390
+ warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${childrenField}`])
384
391
  }
385
392
  })
386
393
  }
387
394
  treeData = XEUtils.toArrayTree(fullData, {
388
395
  key: treeOpts.rowField,
389
396
  parentKey: treeOpts.parentField,
390
- children: treeOpts.children,
391
- mapChildren: treeOpts.mapChildren
397
+ children: childrenField,
398
+ mapChildren: treeOpts.mapChildrenField
392
399
  })
393
400
  fullData = treeData.slice(0)
394
401
  } else {
@@ -592,6 +599,8 @@ const Methods = {
592
599
  cacheRowMap (source) {
593
600
  const { treeConfig, treeOpts, tableFullData, fullDataRowMap, fullAllDataRowMap, tableFullTreeData } = this
594
601
  let { fullDataRowIdData, fullAllDataRowIdData } = this
602
+ const childrenField = treeOpts.children || treeOpts.childrenField
603
+ const hasChildField = treeOpts.hasChild || treeOpts.hasChildField
595
604
  const rowkey = getRowkey(this)
596
605
  const isLazy = treeConfig && treeOpts.lazy
597
606
  const handleCache = (row, index, items, path, parent, nodes) => {
@@ -602,8 +611,8 @@ const Methods = {
602
611
  rowid = getRowUniqueId()
603
612
  XEUtils.set(row, rowkey, rowid)
604
613
  }
605
- if (isLazy && row[treeOpts.hasChild] && XEUtils.isUndefined(row[treeOpts.children])) {
606
- row[treeOpts.children] = null
614
+ if (isLazy && row[hasChildField] && XEUtils.isUndefined(row[childrenField])) {
615
+ row[childrenField] = null
607
616
  }
608
617
  const rest = { row, rowid, seq, index: treeConfig && parent ? -1 : index, _index: -1, $index: -1, items, parent, level }
609
618
  if (source) {
@@ -620,7 +629,7 @@ const Methods = {
620
629
  fullAllDataRowIdData = this.fullAllDataRowIdData = {}
621
630
  fullAllDataRowMap.clear()
622
631
  if (treeConfig) {
623
- XEUtils.eachTree(tableFullTreeData, handleCache, treeOpts)
632
+ XEUtils.eachTree(tableFullTreeData, handleCache, { children: childrenField })
624
633
  } else {
625
634
  tableFullData.forEach(handleCache)
626
635
  }
@@ -643,24 +652,30 @@ const Methods = {
643
652
  }
644
653
  // 源数据缓存
645
654
  if (treeConfig && !treeOpts.transform) {
646
- XEUtils.eachTree(sourceData, handleSourceRow, treeOpts)
655
+ const childrenField = treeOpts.children || treeOpts.childrenField
656
+ XEUtils.eachTree(sourceData, handleSourceRow, { children: treeOpts.transform ? treeOpts.mapChildrenField : childrenField })
647
657
  } else {
648
658
  sourceData.forEach(handleSourceRow)
649
659
  }
650
660
  this.tableSourceData = sourceData
651
661
  },
652
662
  loadTreeChildren (row, childRecords) {
653
- const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData } = this
654
- const { transform, children, mapChildren } = treeOpts
663
+ const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData, sourceDataRowIdData } = this
664
+ const { transform, mapChildrenField } = treeOpts
665
+ const childrenField = treeOpts.children || treeOpts.childrenField
655
666
  const rest = fullAllDataRowIdData[getRowid(this, row)]
656
667
  const parentLevel = rest ? rest.level : 0
657
668
  return this.createData(childRecords).then((rows) => {
658
669
  if (keepSource) {
659
670
  const rowid = getRowid(this, row)
660
- const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid(this, item), treeOpts)
671
+ const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid(this, item), { children: childrenField })
661
672
  if (matchObj) {
662
- matchObj.item[children] = XEUtils.clone(rows, true)
673
+ matchObj.item[childrenField] = XEUtils.clone(rows, true)
663
674
  }
675
+ rows.forEach(childRow => {
676
+ const rowid = getRowid(this, childRow)
677
+ sourceDataRowIdData[rowid] = XEUtils.clone(childRow, true)
678
+ })
664
679
  }
665
680
  XEUtils.eachTree(rows, (childRow, index, items, path, parent, nodes) => {
666
681
  const rowid = getRowid(this, childRow)
@@ -669,10 +684,10 @@ const Methods = {
669
684
  fullDataRowMap.set(childRow, rest)
670
685
  fullAllDataRowIdData[rowid] = rest
671
686
  fullAllDataRowMap.set(childRow, rest)
672
- }, treeOpts)
673
- row[children] = rows
687
+ }, { children: childrenField })
688
+ row[childrenField] = rows
674
689
  if (transform) {
675
- row[mapChildren] = rows
690
+ row[mapChildrenField] = rows
676
691
  }
677
692
  this.updateAfterDataIndex()
678
693
  return rows
@@ -930,6 +945,7 @@ const Methods = {
930
945
  */
931
946
  defineField (records) {
932
947
  const { radioOpts, checkboxOpts, treeConfig, treeOpts, expandOpts } = this
948
+ const childrenField = treeOpts.children || treeOpts.childrenField
933
949
  const rowkey = getRowkey(this)
934
950
  if (!XEUtils.isArray(records)) {
935
951
  records = [records || {}]
@@ -956,8 +972,8 @@ const Methods = {
956
972
  XEUtils.set(record, key, null)
957
973
  }
958
974
  })
959
- if (treeConfig && treeOpts.lazy && XEUtils.isUndefined(record[treeOpts.children])) {
960
- record[treeOpts.children] = null
975
+ if (treeConfig && treeOpts.lazy && XEUtils.isUndefined(record[childrenField])) {
976
+ record[childrenField] = null
961
977
  }
962
978
  // 必须有行数据的唯一主键,可以自行设置;也可以默认生成一个随机数
963
979
  if (eqEmptyValue(XEUtils.get(record, rowkey))) {
@@ -1155,24 +1171,25 @@ const Methods = {
1155
1171
  * 用于多选行,获取已选中的数据
1156
1172
  */
1157
1173
  getCheckboxRecords (isFull) {
1158
- const { tableFullData, afterFullData, treeConfig, treeOpts, checkboxOpts, tableFullTreeData, afterTreeFullData } = this
1159
- const { transform, children, mapChildren } = treeOpts
1174
+ const { tableFullData, afterFullData, treeConfig, treeOpts, checkboxOpts, tableFullTreeData, afterTreeFullData, afterFullRowMaps } = this
1175
+ const { transform, mapChildrenField } = treeOpts
1160
1176
  const { checkField } = checkboxOpts
1177
+ const childrenField = treeOpts.children || treeOpts.childrenField
1161
1178
  const currTableData = isFull ? (transform ? tableFullTreeData : tableFullData) : (transform ? afterTreeFullData : afterFullData)
1162
1179
  let rowList = []
1163
1180
  if (checkField) {
1164
1181
  if (treeConfig) {
1165
- rowList = XEUtils.filterTree(currTableData, row => XEUtils.get(row, checkField), { children: transform ? mapChildren : children })
1182
+ rowList = XEUtils.filterTree(currTableData, row => XEUtils.get(row, checkField), { children: transform ? mapChildrenField : childrenField })
1166
1183
  } else {
1167
1184
  rowList = currTableData.filter(row => XEUtils.get(row, checkField))
1168
1185
  }
1169
1186
  } else {
1170
- const { selectCheckboxRows } = this
1171
- if (treeConfig) {
1172
- rowList = XEUtils.filterTree(currTableData, row => this.findRowIndexOf(selectCheckboxRows, row) > -1, { children: transform ? mapChildren : children })
1173
- } else {
1174
- rowList = currTableData.filter(row => this.findRowIndexOf(selectCheckboxRows, row) > -1)
1175
- }
1187
+ const { selectCheckboxMaps, fullDataRowIdData } = this
1188
+ XEUtils.each(selectCheckboxMaps, (row, rowid) => {
1189
+ if (isFull ? fullDataRowIdData[rowid] : afterFullRowMaps[rowid]) {
1190
+ rowList.push(row)
1191
+ }
1192
+ })
1176
1193
  }
1177
1194
  return rowList
1178
1195
  },
@@ -1181,16 +1198,18 @@ const Methods = {
1181
1198
  * @returns
1182
1199
  */
1183
1200
  handleVirtualTreeToList () {
1184
- const { treeOpts, treeConfig, treeExpandeds, afterTreeFullData, afterFullData } = this
1201
+ const { treeOpts, treeConfig, treeExpandedMaps, afterTreeFullData, afterFullData } = this
1185
1202
  if (treeConfig && treeOpts.transform) {
1186
1203
  const fullData = []
1187
- const expandMaps = new Map()
1204
+ const expandMaps = {}
1188
1205
  XEUtils.eachTree(afterTreeFullData, (row, index, items, path, parent) => {
1189
- if (!parent || (expandMaps.has(parent) && treeExpandeds.indexOf(parent) > -1)) {
1190
- expandMaps.set(row, 1)
1206
+ const rowid = getRowid(this, row)
1207
+ const parentRowid = getRowid(this, parent)
1208
+ if (!parent || (expandMaps[parentRowid] && treeExpandedMaps[parentRowid])) {
1209
+ expandMaps[rowid] = 1
1191
1210
  fullData.push(row)
1192
1211
  }
1193
- }, { children: treeOpts.mapChildren })
1212
+ }, { children: treeOpts.mapChildrenField })
1194
1213
  this.afterFullData = fullData
1195
1214
  this.updateScrollYStatus(fullData)
1196
1215
  return fullData
@@ -1314,6 +1333,8 @@ const Methods = {
1314
1333
  */
1315
1334
  updateAfterDataIndex () {
1316
1335
  const { treeConfig, afterFullData, fullDataRowIdData, fullAllDataRowIdData, afterTreeFullData, treeOpts } = this
1336
+ const childrenField = treeOpts.children || treeOpts.childrenField
1337
+ const fullMaps = {}
1317
1338
  if (treeConfig) {
1318
1339
  XEUtils.eachTree(afterTreeFullData, (row, index, items, path) => {
1319
1340
  const rowid = getRowid(this, row)
@@ -1327,7 +1348,8 @@ const Methods = {
1327
1348
  fullAllDataRowIdData[rowid] = rest
1328
1349
  fullDataRowIdData[rowid] = rest
1329
1350
  }
1330
- }, { children: treeOpts.transform ? treeOpts.mapChildren : treeOpts.children })
1351
+ fullMaps[rowid] = row
1352
+ }, { children: treeOpts.transform ? treeOpts.mapChildrenField : childrenField })
1331
1353
  } else {
1332
1354
  afterFullData.forEach((row, index) => {
1333
1355
  const rowid = getRowid(this, row)
@@ -1341,8 +1363,10 @@ const Methods = {
1341
1363
  fullAllDataRowIdData[rowid] = rest
1342
1364
  fullDataRowIdData[rowid] = rest
1343
1365
  }
1366
+ fullMaps[rowid] = row
1344
1367
  })
1345
1368
  }
1369
+ this.afterFullRowMaps = fullMaps
1346
1370
  },
1347
1371
  /**
1348
1372
  * 只对 tree-config 有效,获取行的父级
@@ -1474,7 +1498,7 @@ const Methods = {
1474
1498
  */
1475
1499
  showColumn (fieldOrColumn) {
1476
1500
  const column = handleFieldOrColumn(this, fieldOrColumn)
1477
- if (column && column.visible) {
1501
+ if (column && !column.visible) {
1478
1502
  column.visible = true
1479
1503
  return this.handleCustom()
1480
1504
  }
@@ -2513,6 +2537,7 @@ const Methods = {
2513
2537
  const operArrow = isLeftArrow || isUpArrow || isRightArrow || isDwArrow
2514
2538
  const operCtxMenu = isCtxMenu && ctxMenuStore.visible && (isEnter || isSpacebar || operArrow)
2515
2539
  const isEditStatus = isEnableConf(editConfig) && actived.column && actived.row
2540
+ const childrenField = treeOpts.children || treeOpts.childrenField
2516
2541
  let params
2517
2542
  if (filterStore.visible) {
2518
2543
  if (isEsc) {
@@ -2585,7 +2610,7 @@ const Methods = {
2585
2610
  }
2586
2611
  } else if (treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
2587
2612
  // 如果是树形表格当前行回车移动到子节点
2588
- const childrens = currentRow[treeOpts.children]
2613
+ const childrens = currentRow[childrenField]
2589
2614
  if (childrens && childrens.length) {
2590
2615
  evnt.preventDefault()
2591
2616
  const targetRow = childrens[0]
@@ -2647,7 +2672,7 @@ const Methods = {
2647
2672
  }
2648
2673
  } else if (isBack && keyboardOpts.isArrow && treeConfig && (rowOpts.isCurrent || highlightCurrentRow) && currentRow) {
2649
2674
  // 如果树形表格回退键关闭当前行返回父节点
2650
- const { parent: parentRow } = XEUtils.findTree(this.afterFullData, item => item === currentRow, treeOpts)
2675
+ const { parent: parentRow } = XEUtils.findTree(this.afterFullData, item => item === currentRow, { children: childrenField })
2651
2676
  if (parentRow) {
2652
2677
  evnt.preventDefault()
2653
2678
  params = { $table: this, row: parentRow }
@@ -2913,12 +2938,22 @@ const Methods = {
2913
2938
  * 获取复选框半选状态的行数据
2914
2939
  */
2915
2940
  getCheckboxIndeterminateRecords (isFull) {
2916
- const { treeConfig, treeIndeterminates, fullDataRowIdData } = this
2941
+ const { treeConfig, treeIndeterminateMaps, fullDataRowIdData } = this
2917
2942
  if (treeConfig) {
2918
- return isFull ? treeIndeterminates.slice(0) : treeIndeterminates.filter(row => {
2919
- const rowid = getRowid(this, row)
2920
- return fullDataRowIdData[rowid]
2943
+ const fullRest = []
2944
+ const defRest = []
2945
+ XEUtils.each(treeIndeterminateMaps, (item, rowid) => {
2946
+ if (item) {
2947
+ fullRest.push(item)
2948
+ if (fullDataRowIdData[rowid]) {
2949
+ defRest.push(item)
2950
+ }
2951
+ }
2921
2952
  })
2953
+ if (isFull) {
2954
+ return fullRest
2955
+ }
2956
+ return defRest
2922
2957
  }
2923
2958
  return []
2924
2959
  },
@@ -2956,29 +2991,36 @@ const Methods = {
2956
2991
  return this.handleCheckedCheckboxRow(rows, value, true)
2957
2992
  },
2958
2993
  isCheckedByCheckboxRow (row) {
2959
- const { selectCheckboxRows } = this
2994
+ const { selectCheckboxMaps } = this
2960
2995
  const { checkField } = this.checkboxOpts
2961
2996
  if (checkField) {
2962
2997
  return XEUtils.get(row, checkField)
2963
2998
  }
2964
- return this.findRowIndexOf(selectCheckboxRows, row) > -1
2999
+ return !!selectCheckboxMaps[getRowid(this, row)]
2965
3000
  },
2966
3001
  isIndeterminateByCheckboxRow (row) {
2967
- const { treeIndeterminates } = this
2968
- return this.findRowIndexOf(treeIndeterminates, row) > -1 && !this.isCheckedByCheckboxRow(row)
3002
+ const { treeIndeterminateMaps } = this
3003
+ return !!treeIndeterminateMaps[getRowid(this, row)] && !this.isCheckedByCheckboxRow(row)
2969
3004
  },
2970
3005
  /**
2971
3006
  * 多选,行选中事件
2972
3007
  * value 选中true 不选false 半选-1
2973
3008
  */
2974
3009
  handleSelectRow ({ row }, value, isForce) {
2975
- const { selectCheckboxRows, afterFullData, treeConfig, treeOpts, treeIndeterminates, checkboxOpts } = this
3010
+ const { selectCheckboxMaps, afterFullData, treeConfig, treeOpts, treeIndeterminateMaps, checkboxOpts } = this
2976
3011
  const { checkField, checkStrictly, checkMethod } = checkboxOpts
3012
+ const selectRowMaps = { ...selectCheckboxMaps }
3013
+ const childrenField = treeOpts.children || treeOpts.childrenField
3014
+ const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField
3015
+ const rowid = getRowid(this, row)
2977
3016
  if (checkField) {
2978
3017
  if (treeConfig && !checkStrictly) {
2979
3018
  if (value === -1) {
2980
- if (this.findRowIndexOf(treeIndeterminates, row) === -1) {
2981
- treeIndeterminates.push(row)
3019
+ if (!treeIndeterminateMaps[rowid]) {
3020
+ if (indeterminateField) {
3021
+ XEUtils.set(row, indeterminateField, true)
3022
+ }
3023
+ treeIndeterminateMaps[rowid] = row
2982
3024
  }
2983
3025
  XEUtils.set(row, checkField, false)
2984
3026
  } else {
@@ -2986,23 +3028,48 @@ const Methods = {
2986
3028
  XEUtils.eachTree([row], (item) => {
2987
3029
  if (this.eqRow(item, row) || (isForce || (!checkMethod || checkMethod({ row: item })))) {
2988
3030
  XEUtils.set(item, checkField, value)
2989
- XEUtils.remove(treeIndeterminates, half => this.eqRow(half, item))
3031
+ if (indeterminateField) {
3032
+ XEUtils.set(row, indeterminateField, false)
3033
+ }
3034
+ delete treeIndeterminateMaps[getRowid(this, item)]
2990
3035
  this.handleCheckboxReserveRow(row, value)
2991
3036
  }
2992
- }, treeOpts)
3037
+ }, { children: childrenField })
2993
3038
  }
2994
3039
  // 如果存在父节点,更新父节点状态
2995
- const matchObj = XEUtils.findTree(afterFullData, item => this.eqRow(item, row), treeOpts)
3040
+ const matchObj = XEUtils.findTree(afterFullData, item => this.eqRow(item, row), { children: childrenField })
2996
3041
  if (matchObj && matchObj.parent) {
2997
3042
  let parentStatus
2998
- const vItems = !isForce && checkMethod ? matchObj.items.filter((item) => checkMethod({ row: item })) : matchObj.items
2999
- const indeterminatesItem = XEUtils.find(matchObj.items, item => this.findRowIndexOf(treeIndeterminates, item) > -1)
3043
+ const vItems = []
3044
+ const vItemMaps = {}
3045
+ if (!isForce && checkMethod) {
3046
+ matchObj.items.forEach((item) => {
3047
+ if (checkMethod({ row: item })) {
3048
+ const itemRid = getRowid(this, item)
3049
+ vItemMaps[itemRid] = item
3050
+ vItems.push(item)
3051
+ }
3052
+ })
3053
+ } else {
3054
+ matchObj.items.forEach(item => {
3055
+ const itemRid = getRowid(this, item)
3056
+ vItemMaps[itemRid] = item
3057
+ vItems.push(item)
3058
+ })
3059
+ }
3060
+ const indeterminatesItem = XEUtils.find(matchObj.items, item => !!treeIndeterminateMaps[getRowid(this, item)])
3000
3061
  if (indeterminatesItem) {
3001
3062
  parentStatus = -1
3002
3063
  } else {
3003
- const selectItems = matchObj.items.filter(item => XEUtils.get(item, checkField))
3004
- parentStatus = selectItems.filter(item => this.findRowIndexOf(vItems, item) > -1).length === vItems.length ? true : (selectItems.length || value === -1 ? -1 : false)
3064
+ const selectItems = []
3065
+ matchObj.items.forEach(item => {
3066
+ if (XEUtils.get(item, checkField)) {
3067
+ selectItems.push(item)
3068
+ }
3069
+ })
3070
+ parentStatus = selectItems.filter(item => vItemMaps[getRowid(this, item)]).length === vItems.length ? true : (selectItems.length || value === -1 ? -1 : false)
3005
3071
  }
3072
+ this.selectCheckboxMaps = selectRowMaps
3006
3073
  return this.handleSelectRow({ row: matchObj.parent }, parentStatus, isForce)
3007
3074
  }
3008
3075
  } else {
@@ -3014,58 +3081,100 @@ const Methods = {
3014
3081
  } else {
3015
3082
  if (treeConfig && !checkStrictly) {
3016
3083
  if (value === -1) {
3017
- if (this.findRowIndexOf(treeIndeterminates, row) === -1) {
3018
- treeIndeterminates.push(row)
3084
+ if (!treeIndeterminateMaps[rowid]) {
3085
+ if (indeterminateField) {
3086
+ XEUtils.set(row, indeterminateField, true)
3087
+ }
3088
+ treeIndeterminateMaps[rowid] = row
3089
+ }
3090
+ if (selectRowMaps[rowid]) {
3091
+ delete selectRowMaps[rowid]
3019
3092
  }
3020
- XEUtils.remove(selectCheckboxRows, item => this.eqRow(item, row))
3021
3093
  } else {
3022
3094
  // 更新子节点状态
3023
3095
  XEUtils.eachTree([row], (item) => {
3096
+ const itemRid = getRowid(this, item)
3024
3097
  if (this.eqRow(item, row) || (isForce || (!checkMethod || checkMethod({ row: item })))) {
3025
3098
  if (value) {
3026
- selectCheckboxRows.push(item)
3099
+ selectRowMaps[itemRid] = item
3027
3100
  } else {
3028
- XEUtils.remove(selectCheckboxRows, select => this.eqRow(select, item))
3101
+ if (selectRowMaps[itemRid]) {
3102
+ delete selectRowMaps[itemRid]
3103
+ }
3104
+ }
3105
+ if (indeterminateField) {
3106
+ XEUtils.set(row, indeterminateField, false)
3029
3107
  }
3030
- XEUtils.remove(treeIndeterminates, half => this.eqRow(half, item))
3108
+ delete treeIndeterminateMaps[getRowid(this, item)]
3031
3109
  this.handleCheckboxReserveRow(row, value)
3032
3110
  }
3033
- }, treeOpts)
3111
+ }, { children: childrenField })
3034
3112
  }
3035
3113
  // 如果存在父节点,更新父节点状态
3036
- const matchObj = XEUtils.findTree(afterFullData, item => this.eqRow(item, row), treeOpts)
3114
+ const matchObj = XEUtils.findTree(afterFullData, item => this.eqRow(item, row), { children: childrenField })
3037
3115
  if (matchObj && matchObj.parent) {
3038
3116
  let parentStatus
3039
- const vItems = !isForce && checkMethod ? matchObj.items.filter((item) => checkMethod({ row: item })) : matchObj.items
3040
- const indeterminatesItem = XEUtils.find(matchObj.items, item => this.findRowIndexOf(treeIndeterminates, item) > -1)
3117
+ const vItems = []
3118
+ const vItemMaps = {}
3119
+ if (!isForce && checkMethod) {
3120
+ matchObj.items.forEach((item) => {
3121
+ if (checkMethod({ row: item })) {
3122
+ const itemRid = getRowid(this, item)
3123
+ vItemMaps[itemRid] = item
3124
+ vItems.push(item)
3125
+ }
3126
+ })
3127
+ } else {
3128
+ matchObj.items.forEach(item => {
3129
+ const itemRid = getRowid(this, item)
3130
+ vItemMaps[itemRid] = item
3131
+ vItems.push(item)
3132
+ })
3133
+ }
3134
+ const indeterminatesItem = XEUtils.find(matchObj.items, item => !!treeIndeterminateMaps[getRowid(this, item)])
3041
3135
  if (indeterminatesItem) {
3042
3136
  parentStatus = -1
3043
3137
  } else {
3044
- const selectItems = matchObj.items.filter(item => this.findRowIndexOf(selectCheckboxRows, item) > -1)
3045
- parentStatus = selectItems.filter(item => this.findRowIndexOf(vItems, item) > -1).length === vItems.length ? true : (selectItems.length || value === -1 ? -1 : false)
3138
+ const selectItems = []
3139
+ matchObj.items.forEach(item => {
3140
+ const itemRid = getRowid(this, item)
3141
+ if (selectRowMaps[itemRid]) {
3142
+ selectItems.push(item)
3143
+ }
3144
+ })
3145
+ parentStatus = selectItems.filter(item => vItemMaps[getRowid(this, item)]).length === vItems.length ? true : (selectItems.length || value === -1 ? -1 : false)
3046
3146
  }
3147
+ this.selectCheckboxMaps = selectRowMaps
3047
3148
  return this.handleSelectRow({ row: matchObj.parent }, parentStatus, isForce)
3048
3149
  }
3049
3150
  } else {
3050
3151
  if (isForce || (!checkMethod || checkMethod({ row }))) {
3051
3152
  if (value) {
3052
- if (this.findRowIndexOf(selectCheckboxRows, row) === -1) {
3053
- selectCheckboxRows.push(row)
3153
+ if (!selectRowMaps[rowid]) {
3154
+ selectRowMaps[rowid] = row
3054
3155
  }
3055
3156
  } else {
3056
- XEUtils.remove(selectCheckboxRows, item => this.eqRow(item, row))
3157
+ if (selectRowMaps[rowid]) {
3158
+ delete selectRowMaps[rowid]
3159
+ }
3057
3160
  }
3058
3161
  this.handleCheckboxReserveRow(row, value)
3059
3162
  }
3060
3163
  }
3061
3164
  }
3165
+ this.selectCheckboxMaps = selectRowMaps
3062
3166
  this.checkSelectionStatus()
3063
3167
  },
3064
3168
  handleToggleCheckRowEvent (evnt, params) {
3065
- const { selectCheckboxRows, checkboxOpts } = this
3169
+ const { selectCheckboxMaps, checkboxOpts } = this
3066
3170
  const { checkField } = checkboxOpts
3067
3171
  const { row } = params
3068
- const value = checkField ? !XEUtils.get(row, checkField) : this.findRowIndexOf(selectCheckboxRows, row) === -1
3172
+ let value = false
3173
+ if (checkField) {
3174
+ value = !XEUtils.get(row, checkField)
3175
+ } else {
3176
+ value = !selectCheckboxMaps[getRowid(this, row)]
3177
+ }
3069
3178
  if (evnt) {
3070
3179
  this.triggerCheckRowEvent(evnt, params, value)
3071
3180
  } else {
@@ -3073,8 +3182,25 @@ const Methods = {
3073
3182
  }
3074
3183
  },
3075
3184
  triggerCheckRowEvent (evnt, params, value) {
3076
- const { checkMethod } = this.checkboxOpts
3077
- if (!checkMethod || checkMethod({ row: params.row })) {
3185
+ const { checkboxOpts, afterFullData } = this
3186
+ const { checkMethod } = checkboxOpts
3187
+ const { row } = params
3188
+ if (checkboxOpts.isShiftKey && evnt.shiftKey && !this.treeConfig) {
3189
+ const checkboxRecords = this.getCheckboxRecords()
3190
+ if (checkboxRecords.length) {
3191
+ const firstRow = checkboxRecords[0]
3192
+ const _rowIndex = this.getVTRowIndex(row)
3193
+ const _firstRowIndex = this.getVTRowIndex(firstRow)
3194
+ if (_rowIndex !== _firstRowIndex) {
3195
+ this.setAllCheckboxRow(false)
3196
+ const rangeRows = _rowIndex < _firstRowIndex ? afterFullData.slice(_rowIndex, _firstRowIndex + 1) : afterFullData.slice(_firstRowIndex, _rowIndex + 1)
3197
+ this.handleCheckedCheckboxRow(rangeRows, true, false)
3198
+ this.emitEvent('checkbox-range-select', Object.assign({ rangeRecords: rangeRows }, params), evnt)
3199
+ return
3200
+ }
3201
+ }
3202
+ }
3203
+ if (!checkMethod || checkMethod({ row })) {
3078
3204
  this.handleSelectRow(params, value)
3079
3205
  this.emitEvent('checkbox-change', Object.assign({
3080
3206
  records: this.getCheckboxRecords(),
@@ -3088,17 +3214,29 @@ const Methods = {
3088
3214
  * 多选,切换某一行的选中状态
3089
3215
  */
3090
3216
  toggleCheckboxRow (row) {
3091
- const { selectCheckboxRows, checkboxOpts } = this
3217
+ const { selectCheckboxMaps, checkboxOpts } = this
3092
3218
  const { checkField } = checkboxOpts
3093
- const value = checkField ? !XEUtils.get(row, checkField) : this.findRowIndexOf(selectCheckboxRows, row) === -1
3219
+ const value = checkField ? !XEUtils.get(row, checkField) : !selectCheckboxMaps[getRowid(this, row)]
3094
3220
  this.handleSelectRow({ row }, value, true)
3095
3221
  return this.$nextTick()
3096
3222
  },
3097
3223
  handleCheckedAllCheckboxRow (value, isForce) {
3098
- const { afterFullData, treeConfig, treeOpts, selectCheckboxRows, checkboxReserveRowMap, checkboxOpts } = this
3224
+ const { afterFullData, treeConfig, treeOpts, selectCheckboxMaps, checkboxReserveRowMap, checkboxOpts, afterFullRowMaps } = this
3099
3225
  const { checkField, reserve, checkStrictly, checkMethod } = checkboxOpts
3100
- let selectRows = []
3101
- const beforeSelection = treeConfig ? [] : selectCheckboxRows.filter(row => this.findRowIndexOf(afterFullData, row) === -1)
3226
+ const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField
3227
+ const childrenField = treeOpts.children || treeOpts.childrenField
3228
+ const selectRowMaps = {}
3229
+
3230
+ // 疑惑!
3231
+ if (!treeConfig) {
3232
+ XEUtils.each(selectCheckboxMaps, (row, rowid) => {
3233
+ if (!afterFullRowMaps[rowid]) {
3234
+ selectRowMaps[rowid] = row
3235
+ }
3236
+ })
3237
+ }
3238
+ // 疑惑!
3239
+
3102
3240
  if (checkStrictly) {
3103
3241
  this.isAllSelected = value
3104
3242
  } else {
@@ -3110,15 +3248,18 @@ const Methods = {
3110
3248
  const checkValFn = (row) => {
3111
3249
  if (isForce || (!checkMethod || checkMethod({ row }))) {
3112
3250
  if (value) {
3113
- selectRows.push(row)
3251
+ selectRowMaps[getRowid(this, row)] = row
3114
3252
  }
3115
3253
  XEUtils.set(row, checkField, value)
3116
3254
  }
3255
+ if (treeConfig && indeterminateField) {
3256
+ XEUtils.set(row, indeterminateField, false)
3257
+ }
3117
3258
  }
3118
3259
  // 如果存在选中方法
3119
3260
  // 如果方法成立,则更新值,否则忽略该数据
3120
3261
  if (treeConfig) {
3121
- XEUtils.eachTree(afterFullData, checkValFn, treeOpts)
3262
+ XEUtils.eachTree(afterFullData, checkValFn, { children: childrenField })
3122
3263
  } else {
3123
3264
  afterFullData.forEach(checkValFn)
3124
3265
  }
@@ -3135,9 +3276,9 @@ const Methods = {
3135
3276
  */
3136
3277
  XEUtils.eachTree(afterFullData, (row) => {
3137
3278
  if (isForce || (!checkMethod || checkMethod({ row }))) {
3138
- selectRows.push(row)
3279
+ selectRowMaps[getRowid(this, row)] = row
3139
3280
  }
3140
- }, treeOpts)
3281
+ }, { children: childrenField })
3141
3282
  } else {
3142
3283
  /**
3143
3284
  * 如果是树取消
@@ -3145,10 +3286,11 @@ const Methods = {
3145
3286
  */
3146
3287
  if (!isForce && checkMethod) {
3147
3288
  XEUtils.eachTree(afterFullData, (row) => {
3148
- if (checkMethod({ row }) ? 0 : this.findRowIndexOf(selectCheckboxRows, row) > -1) {
3149
- selectRows.push(row)
3289
+ const rowid = getRowid(this, row)
3290
+ if (checkMethod({ row }) ? 0 : selectCheckboxMaps[rowid]) {
3291
+ selectRowMaps[rowid] = row
3150
3292
  }
3151
- }, treeOpts)
3293
+ }, { children: childrenField })
3152
3294
  }
3153
3295
  }
3154
3296
  } else {
@@ -3159,9 +3301,16 @@ const Methods = {
3159
3301
  * 如果不存在选中方法,则添加所有数据到临时集合中
3160
3302
  */
3161
3303
  if (!isForce && checkMethod) {
3162
- selectRows = afterFullData.filter((row) => this.findRowIndexOf(selectCheckboxRows, row) > -1 || checkMethod({ row }))
3304
+ afterFullData.forEach((row) => {
3305
+ const rowid = getRowid(this, row)
3306
+ if (selectCheckboxMaps[rowid] || checkMethod({ row })) {
3307
+ selectRowMaps[rowid] = row
3308
+ }
3309
+ })
3163
3310
  } else {
3164
- selectRows = afterFullData.slice(0)
3311
+ afterFullData.forEach(row => {
3312
+ selectRowMaps[getRowid(this, row)] = row
3313
+ })
3165
3314
  }
3166
3315
  } else {
3167
3316
  /**
@@ -3170,23 +3319,29 @@ const Methods = {
3170
3319
  * 如果不存在选中方法,无需处理,临时集合默认为空
3171
3320
  */
3172
3321
  if (!isForce && checkMethod) {
3173
- selectRows = afterFullData.filter((row) => checkMethod({ row }) ? 0 : this.findRowIndexOf(selectCheckboxRows, row) > -1)
3322
+ afterFullData.forEach((row) => {
3323
+ const rowid = getRowid(this, row)
3324
+ if (checkMethod({ row }) ? 0 : selectCheckboxMaps[rowid]) {
3325
+ selectRowMaps[rowid] = row
3326
+ }
3327
+ })
3174
3328
  }
3175
3329
  }
3176
3330
  }
3177
3331
  }
3178
3332
  if (reserve) {
3179
3333
  if (value) {
3180
- selectRows.forEach(row => {
3181
- checkboxReserveRowMap[getRowid(this, row)] = row
3334
+ XEUtils.each(selectRowMaps, (row, rowid) => {
3335
+ checkboxReserveRowMap[rowid] = row
3182
3336
  })
3183
3337
  } else {
3184
- afterFullData.forEach(row => this.handleCheckboxReserveRow(row, false))
3338
+ afterFullData.forEach((row) => this.handleCheckboxReserveRow(row, false))
3185
3339
  }
3186
3340
  }
3187
- this.selectCheckboxRows = checkField ? [] : beforeSelection.concat(selectRows)
3341
+ this.selectCheckboxMaps = checkField ? {} : selectRowMaps
3188
3342
  }
3189
- this.treeIndeterminates = []
3343
+ this.treeIndeterminateMaps = {}
3344
+ this.treeIndeterminateRowMaps = {}
3190
3345
  this.checkSelectionStatus()
3191
3346
  return this.$nextTick()
3192
3347
  },
@@ -3198,8 +3353,9 @@ const Methods = {
3198
3353
  return this.handleCheckedAllCheckboxRow(value, true)
3199
3354
  },
3200
3355
  checkSelectionStatus () {
3201
- const { afterFullData, selectCheckboxRows, treeIndeterminates, checkboxOpts, treeConfig } = this
3202
- const { checkField, halfField, checkStrictly, checkMethod } = checkboxOpts
3356
+ const { afterFullData, selectCheckboxMaps, treeIndeterminateMaps, checkboxOpts, treeConfig } = this
3357
+ const { checkField, checkStrictly, checkMethod } = checkboxOpts
3358
+ const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField
3203
3359
  if (!checkStrictly) {
3204
3360
  const disableRows = []
3205
3361
  const checkRows = []
@@ -3224,16 +3380,16 @@ const Methods = {
3224
3380
  )
3225
3381
  isAllSelected = isAllResolve && afterFullData.length !== disableRows.length
3226
3382
  if (treeConfig) {
3227
- if (halfField) {
3228
- isIndeterminate = !isAllSelected && afterFullData.some(row => XEUtils.get(row, checkField) || XEUtils.get(row, halfField) || this.findRowIndexOf(treeIndeterminates, row) > -1)
3383
+ if (indeterminateField) {
3384
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => XEUtils.get(row, checkField) || XEUtils.get(row, indeterminateField) || !!treeIndeterminateMaps[getRowid(this, row)])
3229
3385
  } else {
3230
- isIndeterminate = !isAllSelected && afterFullData.some(row => XEUtils.get(row, checkField) || this.findRowIndexOf(treeIndeterminates, row) > -1)
3386
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => XEUtils.get(row, checkField) || !!treeIndeterminateMaps[getRowid(this, row)])
3231
3387
  }
3232
3388
  } else {
3233
- if (halfField) {
3234
- isIndeterminate = !isAllSelected && afterFullData.some(row => XEUtils.get(row, checkField) || XEUtils.get(row, halfField))
3389
+ if (indeterminateField) {
3390
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => XEUtils.get(row, checkField) || XEUtils.get(row, indeterminateField))
3235
3391
  } else {
3236
- isIndeterminate = !isAllSelected && afterFullData.some(row => XEUtils.get(row, checkField))
3392
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => XEUtils.get(row, checkField))
3237
3393
  }
3238
3394
  }
3239
3395
  } else {
@@ -3244,19 +3400,22 @@ const Methods = {
3244
3400
  disableRows.push(row)
3245
3401
  return true
3246
3402
  }
3247
- if (this.findRowIndexOf(selectCheckboxRows, row) > -1) {
3403
+ if (selectCheckboxMaps[getRowid(this, row)]) {
3248
3404
  checkRows.push(row)
3249
3405
  return true
3250
3406
  }
3251
3407
  return false
3252
3408
  }
3253
- : row => this.findRowIndexOf(selectCheckboxRows, row) > -1
3409
+ : row => selectCheckboxMaps[getRowid(this, row)]
3254
3410
  )
3255
3411
  isAllSelected = isAllResolve && afterFullData.length !== disableRows.length
3256
3412
  if (treeConfig) {
3257
- isIndeterminate = !isAllSelected && afterFullData.some(row => this.findRowIndexOf(treeIndeterminates, row) > -1 || this.findRowIndexOf(selectCheckboxRows, row) > -1)
3413
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => {
3414
+ const itemRid = getRowid(this, row)
3415
+ return treeIndeterminateMaps[itemRid] || selectCheckboxMaps[itemRid]
3416
+ })
3258
3417
  } else {
3259
- isIndeterminate = !isAllSelected && afterFullData.some(row => this.findRowIndexOf(selectCheckboxRows, row) > -1)
3418
+ isIndeterminate = !isAllSelected && afterFullData.some((row) => selectCheckboxMaps[getRowid(this, row)])
3260
3419
  }
3261
3420
  }
3262
3421
  this.isAllSelected = isAllSelected
@@ -3265,10 +3424,10 @@ const Methods = {
3265
3424
  },
3266
3425
  // 还原展开、选中等相关状态
3267
3426
  handleReserveStatus () {
3268
- const { expandColumn, treeOpts, treeConfig, fullDataRowIdData, fullAllDataRowMap, currentRow, selectRow, radioReserveRow, radioOpts, checkboxOpts, selectCheckboxRows, rowExpandeds, treeExpandeds, expandOpts } = this
3427
+ const { expandColumn, treeOpts, treeConfig, fullDataRowIdData, fullAllDataRowMap, currentRow, selectRadioRow, radioReserveRow, radioOpts, checkboxOpts, selectCheckboxMaps, rowExpandedMaps, treeExpandedMaps, expandOpts } = this
3269
3428
  // 单选框
3270
- if (selectRow && !fullAllDataRowMap.has(selectRow)) {
3271
- this.selectRow = null // 刷新单选行状态
3429
+ if (selectRadioRow && !fullAllDataRowMap.has(selectRadioRow)) {
3430
+ this.selectRadioRow = null // 刷新单选行状态
3272
3431
  }
3273
3432
  // 还原保留选中状态
3274
3433
  if (radioOpts.reserve && radioReserveRow) {
@@ -3278,7 +3437,7 @@ const Methods = {
3278
3437
  }
3279
3438
  }
3280
3439
  // 复选框
3281
- this.selectCheckboxRows = getRecoverRow(this, selectCheckboxRows) // 刷新多选行状态
3440
+ this.selectCheckboxMaps = getRecoverRowMaps(this, selectCheckboxMaps) // 刷新多选行状态
3282
3441
  // 还原保留选中状态
3283
3442
  if (checkboxOpts.reserve) {
3284
3443
  this.handleCheckedCheckboxRow(handleReserveRow(this, this.checkboxReserveRowMap), true, true)
@@ -3287,13 +3446,13 @@ const Methods = {
3287
3446
  this.currentRow = null // 刷新当前行状态
3288
3447
  }
3289
3448
  // 行展开
3290
- this.rowExpandeds = expandColumn ? getRecoverRow(this, rowExpandeds) : [] // 刷新行展开状态
3449
+ this.rowExpandedMaps = expandColumn ? getRecoverRowMaps(this, rowExpandedMaps) : [] // 刷新行展开状态
3291
3450
  // 还原保留状态
3292
3451
  if (expandColumn && expandOpts.reserve) {
3293
3452
  this.setRowExpand(handleReserveRow(this, this.rowExpandedReserveRowMap), true)
3294
3453
  }
3295
3454
  // 树展开
3296
- this.treeExpandeds = treeConfig ? getRecoverRow(this, treeExpandeds) : [] // 刷新树展开状态
3455
+ this.treeExpandedMaps = treeConfig ? getRecoverRowMaps(this, treeExpandedMaps) : [] // 刷新树展开状态
3297
3456
  if (treeConfig && treeOpts.reserve) {
3298
3457
  this.setTreeExpand(handleReserveRow(this, this.treeExpandedReserveRowMap), true)
3299
3458
  }
@@ -3303,6 +3462,7 @@ const Methods = {
3303
3462
  */
3304
3463
  getRadioReserveRecord (isFull) {
3305
3464
  const { fullDataRowIdData, radioReserveRow, radioOpts, afterFullData, treeConfig, treeOpts } = this
3465
+ const childrenField = treeOpts.children || treeOpts.childrenField
3306
3466
  if (radioOpts.reserve && radioReserveRow) {
3307
3467
  const rowid = getRowid(this, radioReserveRow)
3308
3468
  if (isFull) {
@@ -3312,7 +3472,7 @@ const Methods = {
3312
3472
  } else {
3313
3473
  const rowkey = getRowkey(this)
3314
3474
  if (treeConfig) {
3315
- const matchObj = XEUtils.findTree(afterFullData, row => rowid === XEUtils.get(row, rowkey), treeOpts)
3475
+ const matchObj = XEUtils.findTree(afterFullData, row => rowid === XEUtils.get(row, rowkey), { children: childrenField })
3316
3476
  if (matchObj) {
3317
3477
  return radioReserveRow
3318
3478
  }
@@ -3340,13 +3500,14 @@ const Methods = {
3340
3500
  */
3341
3501
  getCheckboxReserveRecords (isFull) {
3342
3502
  const { fullDataRowIdData, afterFullData, checkboxReserveRowMap, checkboxOpts, treeConfig, treeOpts } = this
3503
+ const childrenField = treeOpts.children || treeOpts.childrenField
3343
3504
  const reserveSelection = []
3344
3505
  if (checkboxOpts.reserve) {
3345
3506
  const afterFullIdMaps = {}
3346
3507
  if (treeConfig) {
3347
3508
  XEUtils.eachTree(afterFullData, row => {
3348
3509
  afterFullIdMaps[getRowid(this, row)] = 1
3349
- }, treeOpts)
3510
+ }, { children: childrenField })
3350
3511
  } else {
3351
3512
  afterFullData.forEach(row => {
3352
3513
  afterFullIdMaps[getRowid(this, row)] = 1
@@ -3404,11 +3565,19 @@ const Methods = {
3404
3565
  clearCheckboxRow () {
3405
3566
  const { tableFullData, treeConfig, treeOpts, checkboxOpts } = this
3406
3567
  const { checkField, reserve } = checkboxOpts
3568
+ const childrenField = treeOpts.children || treeOpts.childrenField
3569
+ const indeterminateField = checkboxOpts.indeterminateField || checkboxOpts.halfField
3407
3570
  if (checkField) {
3571
+ const handleClearChecked = (item) => {
3572
+ if (treeConfig && indeterminateField) {
3573
+ XEUtils.set(item, indeterminateField, false)
3574
+ }
3575
+ XEUtils.set(item, checkField, false)
3576
+ }
3408
3577
  if (treeConfig) {
3409
- XEUtils.eachTree(tableFullData, item => XEUtils.set(item, checkField, false), treeOpts)
3578
+ XEUtils.eachTree(tableFullData, handleClearChecked, { children: childrenField })
3410
3579
  } else {
3411
- tableFullData.forEach(item => XEUtils.set(item, checkField, false))
3580
+ tableFullData.forEach(handleClearChecked)
3412
3581
  }
3413
3582
  }
3414
3583
  if (reserve) {
@@ -3416,8 +3585,8 @@ const Methods = {
3416
3585
  }
3417
3586
  this.isAllSelected = false
3418
3587
  this.isIndeterminate = false
3419
- this.selectCheckboxRows = []
3420
- this.treeIndeterminates = []
3588
+ this.selectCheckboxMaps = {}
3589
+ this.treeIndeterminateMaps = {}
3421
3590
  return this.$nextTick()
3422
3591
  },
3423
3592
  /**
@@ -3440,7 +3609,7 @@ const Methods = {
3440
3609
  * 单选,行选中事件
3441
3610
  */
3442
3611
  triggerRadioRowEvent (evnt, params) {
3443
- const { selectRow: oldValue, radioOpts } = this
3612
+ const { selectRadioRow: oldValue, radioOpts } = this
3444
3613
  const { row } = params
3445
3614
  let newValue = row
3446
3615
  let isChange = oldValue !== newValue
@@ -3483,13 +3652,13 @@ const Methods = {
3483
3652
  return this.$nextTick()
3484
3653
  },
3485
3654
  isCheckedByRadioRow (row) {
3486
- return this.selectRow === row
3655
+ return this.selectRadioRow === row
3487
3656
  },
3488
3657
  handleCheckedRadioRow (row, isForce) {
3489
3658
  const { radioOpts } = this
3490
3659
  const { checkMethod } = radioOpts
3491
3660
  if (row && (isForce || (!checkMethod || checkMethod({ row })))) {
3492
- this.selectRow = row
3661
+ this.selectRadioRow = row
3493
3662
  this.handleRadioReserveRow(row)
3494
3663
  }
3495
3664
  return this.$nextTick()
@@ -3517,7 +3686,7 @@ const Methods = {
3517
3686
  * 用于单选行,手动清空用户的选择
3518
3687
  */
3519
3688
  clearRadioRow () {
3520
- this.selectRow = null
3689
+ this.selectRadioRow = null
3521
3690
  return this.$nextTick()
3522
3691
  },
3523
3692
  /**
@@ -3530,24 +3699,16 @@ const Methods = {
3530
3699
  * 用于单选行,获取当已选中的数据
3531
3700
  */
3532
3701
  getRadioRecord (isFull) {
3533
- const { treeConfig, treeOpts, selectRow, fullDataRowIdData, afterFullData } = this
3534
- if (selectRow) {
3535
- const rowid = getRowid(this, selectRow)
3702
+ const { selectRadioRow, fullDataRowIdData, afterFullRowMaps } = this
3703
+ if (selectRadioRow) {
3704
+ const rowid = getRowid(this, selectRadioRow)
3536
3705
  if (isFull) {
3537
3706
  if (!fullDataRowIdData[rowid]) {
3538
- return selectRow
3707
+ return selectRadioRow
3539
3708
  }
3540
3709
  } else {
3541
- if (treeConfig) {
3542
- const rowkey = getRowkey(this)
3543
- const matchObj = XEUtils.findTree(afterFullData, row => rowid === XEUtils.get(row, rowkey), treeOpts)
3544
- if (matchObj) {
3545
- return selectRow
3546
- }
3547
- } else {
3548
- if (afterFullData.indexOf(selectRow) > -1) {
3549
- return selectRow
3550
- }
3710
+ if (afterFullRowMaps[rowid]) {
3711
+ return selectRadioRow
3551
3712
  }
3552
3713
  }
3553
3714
  }
@@ -3911,12 +4072,17 @@ const Methods = {
3911
4072
  return rest && rest.expandLoaded
3912
4073
  },
3913
4074
  clearRowExpandLoaded (row) {
3914
- const { expandOpts, expandLazyLoadeds, fullAllDataRowMap } = this
4075
+ const { expandOpts, rowExpandLazyLoadedMaps, fullAllDataRowMap } = this
3915
4076
  const { lazy } = expandOpts
4077
+ const rowid = getRowid(this, row)
3916
4078
  const rest = fullAllDataRowMap.get(row)
3917
4079
  if (lazy && rest) {
3918
4080
  rest.expandLoaded = false
3919
- XEUtils.remove(expandLazyLoadeds, item => this.eqRow(item, row))
4081
+ const rowTempExpandLazyLoadedMaps = { ...rowExpandLazyLoadedMaps }
4082
+ if (rowTempExpandLazyLoadedMaps[rowid]) {
4083
+ delete rowTempExpandLazyLoadedMaps[rowid]
4084
+ }
4085
+ this.rowExpandLazyLoadedMaps = rowTempExpandLazyLoadedMaps
3920
4086
  }
3921
4087
  return this.$nextTick()
3922
4088
  },
@@ -3925,9 +4091,10 @@ const Methods = {
3925
4091
  * @param {Row} row 行对象
3926
4092
  */
3927
4093
  reloadRowExpand (row) {
3928
- const { expandOpts, expandLazyLoadeds } = this
4094
+ const { expandOpts, rowExpandLazyLoadedMaps } = this
3929
4095
  const { lazy } = expandOpts
3930
- if (lazy && this.findRowIndexOf(expandLazyLoadeds, row) === -1) {
4096
+ const rowid = getRowid(this, row)
4097
+ if (lazy && !rowExpandLazyLoadedMaps[rowid]) {
3931
4098
  this.clearRowExpandLoaded(row)
3932
4099
  .then(() => this.handleAsyncRowExpand(row))
3933
4100
  }
@@ -3944,10 +4111,11 @@ const Methods = {
3944
4111
  * 展开行事件
3945
4112
  */
3946
4113
  triggerRowExpandEvent (evnt, params) {
3947
- const { expandOpts, expandLazyLoadeds, expandColumn: column } = this
4114
+ const { expandOpts, rowExpandLazyLoadedMaps, expandColumn: column } = this
3948
4115
  const { row } = params
3949
4116
  const { lazy } = expandOpts
3950
- if (!lazy || this.findRowIndexOf(expandLazyLoadeds, row) === -1) {
4117
+ const rowid = getRowid(this, row)
4118
+ if (!lazy || !rowExpandLazyLoadedMaps[rowid]) {
3951
4119
  const expanded = !this.isExpandByRow(row)
3952
4120
  const columnIndex = this.getColumnIndex(column)
3953
4121
  const $columnIndex = this.getVMColumnIndex(column)
@@ -3985,29 +4153,48 @@ const Methods = {
3985
4153
  */
3986
4154
  setAllRowExpand (expanded) {
3987
4155
  const { treeConfig, treeOpts, tableFullData, tableFullTreeData } = this
4156
+ const childrenField = treeOpts.children || treeOpts.childrenField
3988
4157
  let expandedRows = []
3989
4158
  if (treeConfig) {
3990
4159
  XEUtils.eachTree(tableFullTreeData, (row) => {
3991
4160
  expandedRows.push(row)
3992
- }, treeOpts)
4161
+ }, { children: childrenField })
3993
4162
  } else {
3994
4163
  expandedRows = tableFullData
3995
4164
  }
3996
4165
  return this.setRowExpand(expandedRows, expanded)
3997
4166
  },
3998
4167
  handleAsyncRowExpand (row) {
3999
- const rest = this.fullAllDataRowMap.get(row)
4168
+ const { fullAllDataRowMap, expandOpts } = this
4169
+ const rest = fullAllDataRowMap.get(row)
4000
4170
  return new Promise(resolve => {
4001
- this.expandLazyLoadeds.push(row)
4002
- this.expandOpts.loadMethod({ $table: this, row, rowIndex: this.getRowIndex(row), $rowIndex: this.getVMRowIndex(row) }).then(() => {
4003
- rest.expandLoaded = true
4004
- this.rowExpandeds.push(row)
4005
- }).catch(() => {
4006
- rest.expandLoaded = false
4007
- }).finally(() => {
4008
- XEUtils.remove(this.expandLazyLoadeds, item => this.eqRow(item, row))
4009
- resolve(this.$nextTick().then(this.recalculate))
4010
- })
4171
+ const { loadMethod } = expandOpts
4172
+ if (loadMethod) {
4173
+ const { rowExpandLazyLoadedMaps } = this
4174
+ const rowTempExpandLazyLoadedMaps = { ...rowExpandLazyLoadedMaps }
4175
+ const rowid = getRowid(this, row)
4176
+ rowTempExpandLazyLoadedMaps[rowid] = row
4177
+ this.rowExpandLazyLoadedMaps = rowTempExpandLazyLoadedMaps
4178
+ loadMethod({ $table: this, row, rowIndex: this.getRowIndex(row), $rowIndex: this.getVMRowIndex(row) }).then(() => {
4179
+ rest.expandLoaded = true
4180
+ const { rowExpandedMaps } = this
4181
+ const rowTempExpandedMaps = { ...rowExpandedMaps }
4182
+ rowTempExpandedMaps[rowid] = row
4183
+ this.rowExpandedMaps = rowTempExpandedMaps
4184
+ }).catch(() => {
4185
+ rest.expandLoaded = false
4186
+ }).finally(() => {
4187
+ const { rowExpandLazyLoadedMaps } = this
4188
+ const rowTempExpandLazyLoadedMaps = { ...rowExpandLazyLoadedMaps }
4189
+ if (rowTempExpandLazyLoadedMaps[rowid]) {
4190
+ delete rowTempExpandLazyLoadedMaps[rowid]
4191
+ }
4192
+ this.rowExpandLazyLoadedMaps = rowTempExpandLazyLoadedMaps
4193
+ resolve(this.$nextTick().then(this.recalculate))
4194
+ })
4195
+ } else {
4196
+ resolve()
4197
+ }
4011
4198
  })
4012
4199
  },
4013
4200
  /**
@@ -4018,8 +4205,8 @@ const Methods = {
4018
4205
  * @param {Boolean} expanded 是否展开
4019
4206
  */
4020
4207
  setRowExpand (rows, expanded) {
4021
- const { fullAllDataRowMap, expandLazyLoadeds, expandOpts, expandColumn: column } = this
4022
- let { rowExpandeds } = this
4208
+ const { rowExpandedMaps, fullAllDataRowIdData, rowExpandLazyLoadedMaps, expandOpts, expandColumn: column } = this
4209
+ let rExpandedMaps = { ...rowExpandedMaps }
4023
4210
  const { reserve, lazy, accordion, toggleMethod } = expandOpts
4024
4211
  const lazyRests = []
4025
4212
  const columnIndex = this.getColumnIndex(column)
@@ -4030,30 +4217,36 @@ const Methods = {
4030
4217
  }
4031
4218
  if (accordion) {
4032
4219
  // 只能同时展开一个
4033
- rowExpandeds = []
4220
+ rExpandedMaps = {}
4034
4221
  rows = rows.slice(rows.length - 1, rows.length)
4035
4222
  }
4036
4223
  const validRows = toggleMethod ? rows.filter(row => toggleMethod({ expanded, column, columnIndex, $columnIndex, row, rowIndex: this.getRowIndex(row), $rowIndex: this.getVMRowIndex(row) })) : rows
4037
4224
  if (expanded) {
4038
4225
  validRows.forEach(row => {
4039
- if (this.findRowIndexOf(rowExpandeds, row) === -1) {
4040
- const rest = fullAllDataRowMap.get(row)
4041
- const isLoad = lazy && !rest.expandLoaded && this.findRowIndexOf(expandLazyLoadeds, row) === -1
4226
+ const rowid = getRowid(this, row)
4227
+ if (!rExpandedMaps[rowid]) {
4228
+ const rest = fullAllDataRowIdData[rowid]
4229
+ const isLoad = lazy && !rest.expandLoaded && !rowExpandLazyLoadedMaps[rowid]
4042
4230
  if (isLoad) {
4043
4231
  lazyRests.push(this.handleAsyncRowExpand(row))
4044
4232
  } else {
4045
- rowExpandeds.push(row)
4233
+ rExpandedMaps[rowid] = row
4046
4234
  }
4047
4235
  }
4048
4236
  })
4049
4237
  } else {
4050
- XEUtils.remove(rowExpandeds, row => this.findRowIndexOf(validRows, row) > -1)
4238
+ validRows.forEach(item => {
4239
+ const rowid = getRowid(this, item)
4240
+ if (rExpandedMaps[rowid]) {
4241
+ delete rExpandedMaps[rowid]
4242
+ }
4243
+ })
4051
4244
  }
4052
4245
  if (reserve) {
4053
4246
  validRows.forEach(row => this.handleRowExpandReserve(row, expanded))
4054
4247
  }
4055
4248
  }
4056
- this.rowExpandeds = rowExpandeds
4249
+ this.rowExpandedMaps = rExpandedMaps
4057
4250
  return Promise.all(lazyRests).then(this.recalculate)
4058
4251
  },
4059
4252
  /**
@@ -4061,22 +4254,23 @@ const Methods = {
4061
4254
  * @param {Row} row 行对象
4062
4255
  */
4063
4256
  isExpandByRow (row) {
4064
- const { rowExpandeds } = this
4065
- return this.findRowIndexOf(rowExpandeds, row) > -1
4257
+ const { rowExpandedMaps } = this
4258
+ const rowid = getRowid(this, row)
4259
+ return !!rowExpandedMaps[rowid]
4066
4260
  },
4067
4261
  /**
4068
4262
  * 手动清空展开行状态,数据会恢复成未展开的状态
4069
4263
  */
4070
4264
  clearRowExpand () {
4071
- const { expandOpts, rowExpandeds, tableFullData } = this
4265
+ const { expandOpts, tableFullData } = this
4072
4266
  const { reserve } = expandOpts
4073
- const isExists = rowExpandeds.length
4074
- this.rowExpandeds = []
4267
+ const expList = this.getRowExpandRecords()
4268
+ this.rowExpandedMaps = {}
4075
4269
  if (reserve) {
4076
4270
  tableFullData.forEach(row => this.handleRowExpandReserve(row, false))
4077
4271
  }
4078
4272
  return this.$nextTick().then(() => {
4079
- if (isExists) {
4273
+ if (expList.length) {
4080
4274
  this.recalculate()
4081
4275
  }
4082
4276
  })
@@ -4097,13 +4291,25 @@ const Methods = {
4097
4291
  }
4098
4292
  },
4099
4293
  getRowExpandRecords () {
4100
- return this.rowExpandeds.slice(0)
4294
+ const rest = []
4295
+ XEUtils.each(this.rowExpandedMaps, item => {
4296
+ if (item) {
4297
+ rest.push(item)
4298
+ }
4299
+ })
4300
+ return rest
4101
4301
  },
4102
4302
  getTreeExpandRecords () {
4103
- return this.treeExpandeds.slice(0)
4303
+ const rest = []
4304
+ XEUtils.each(this.treeExpandedMaps, item => {
4305
+ if (item) {
4306
+ rest.push(item)
4307
+ }
4308
+ })
4309
+ return rest
4104
4310
  },
4105
4311
  /**
4106
- * 获取数表格状态
4312
+ * 获取树表格状态
4107
4313
  */
4108
4314
  getTreeStatus () {
4109
4315
  if (this.treeConfig) {
@@ -4123,12 +4329,15 @@ const Methods = {
4123
4329
  return rest && rest.treeLoaded
4124
4330
  },
4125
4331
  clearTreeExpandLoaded (row) {
4126
- const { treeOpts, treeExpandeds, fullAllDataRowMap } = this
4332
+ const { treeOpts, treeExpandedMaps, fullAllDataRowMap } = this
4127
4333
  const { transform, lazy } = treeOpts
4334
+ const rowid = getRowid(this, row)
4128
4335
  const rest = fullAllDataRowMap.get(row)
4129
4336
  if (lazy && rest) {
4130
4337
  rest.treeLoaded = false
4131
- XEUtils.remove(treeExpandeds, item => row === item)
4338
+ if (treeExpandedMaps[rowid]) {
4339
+ delete treeExpandedMaps[rowid]
4340
+ }
4132
4341
  }
4133
4342
  if (transform) {
4134
4343
  this.handleVirtualTreeToList()
@@ -4141,9 +4350,11 @@ const Methods = {
4141
4350
  * @param {Row} row 行对象
4142
4351
  */
4143
4352
  reloadTreeExpand (row) {
4144
- const { treeOpts, treeLazyLoadeds } = this
4145
- const { transform, lazy, hasChild } = treeOpts
4146
- if (lazy && row[hasChild] && treeLazyLoadeds.indexOf(row) === -1) {
4353
+ const { treeOpts, treeExpandLazyLoadedMaps } = this
4354
+ const { transform, lazy } = treeOpts
4355
+ const hasChildField = treeOpts.hasChild || treeOpts.hasChildField
4356
+ const rowid = getRowid(this, row)
4357
+ if (lazy && row[hasChildField] && !treeExpandLazyLoadedMaps[rowid]) {
4147
4358
  this.clearTreeExpandLoaded(row).then(() => {
4148
4359
  return this.handleAsyncTreeExpandChilds(row)
4149
4360
  }).then(() => {
@@ -4168,10 +4379,11 @@ const Methods = {
4168
4379
  * 展开树节点事件
4169
4380
  */
4170
4381
  triggerTreeExpandEvent (evnt, params) {
4171
- const { treeOpts, treeLazyLoadeds } = this
4382
+ const { treeOpts, treeExpandLazyLoadedMaps } = this
4172
4383
  const { row, column } = params
4173
4384
  const { lazy } = treeOpts
4174
- if (!lazy || treeLazyLoadeds.indexOf(row) === -1) {
4385
+ const rowid = getRowid(this, row)
4386
+ if (!lazy || !treeExpandLazyLoadedMaps[rowid]) {
4175
4387
  const expanded = !this.isTreeExpandByRow(row)
4176
4388
  const columnIndex = this.getColumnIndex(column)
4177
4389
  const $columnIndex = this.getVMColumnIndex(column)
@@ -4192,13 +4404,14 @@ const Methods = {
4192
4404
  const { treeConfig, treeOpts, tableFullData } = this
4193
4405
  if (treeConfig) {
4194
4406
  const { expandAll, expandRowKeys } = treeOpts
4407
+ const childrenField = treeOpts.children || treeOpts.childrenField
4195
4408
  if (expandAll) {
4196
4409
  this.setAllTreeExpand(true)
4197
4410
  } else if (expandRowKeys) {
4198
4411
  const defExpandeds = []
4199
4412
  const rowkey = getRowkey(this)
4200
4413
  expandRowKeys.forEach(rowid => {
4201
- const matchObj = XEUtils.findTree(tableFullData, item => rowid === XEUtils.get(item, rowkey), treeOpts)
4414
+ const matchObj = XEUtils.findTree(tableFullData, item => rowid === XEUtils.get(item, rowkey), { children: childrenField })
4202
4415
  if (matchObj) {
4203
4416
  defExpandeds.push(matchObj.item)
4204
4417
  }
@@ -4208,42 +4421,56 @@ const Methods = {
4208
4421
  }
4209
4422
  },
4210
4423
  handleAsyncTreeExpandChilds (row) {
4211
- const { fullAllDataRowMap, treeExpandeds, treeOpts, treeLazyLoadeds, checkboxOpts } = this
4424
+ const { treeOpts, checkboxOpts } = this
4212
4425
  const { transform, loadMethod } = treeOpts
4213
4426
  const { checkStrictly } = checkboxOpts
4214
- const rest = fullAllDataRowMap.get(row)
4215
4427
  return new Promise(resolve => {
4216
- treeLazyLoadeds.push(row)
4217
- loadMethod({ $table: this, row }).then(childRecords => {
4218
- // 响应成功后则展开行,并将子节点挂载到该节点下
4219
- rest.treeLoaded = true
4220
- XEUtils.remove(treeLazyLoadeds, item => item === row)
4221
- if (!XEUtils.isArray(childRecords)) {
4222
- childRecords = []
4223
- }
4224
- if (childRecords) {
4225
- return this.loadTreeChildren(row, childRecords).then(childRows => {
4226
- if (childRows.length && treeExpandeds.indexOf(row) === -1) {
4227
- treeExpandeds.push(row)
4228
- }
4229
- // 如果当前节点已选中,则展开后子节点也被选中
4230
- if (!checkStrictly && this.isCheckedByCheckboxRow(row)) {
4231
- this.handleCheckedCheckboxRow(childRows, true, true)
4232
- }
4233
- return this.$nextTick().then(() => {
4234
- if (transform) {
4235
- return this.handleTableData()
4428
+ if (loadMethod) {
4429
+ const { fullAllDataRowMap, treeExpandLazyLoadedMaps } = this
4430
+ const rowid = getRowid(this, row)
4431
+ const rest = fullAllDataRowMap.get(row)
4432
+ treeExpandLazyLoadedMaps[rowid] = row
4433
+ loadMethod({ $table: this, row }).then(childRecords => {
4434
+ // 响应成功后则展开行,并将子节点挂载到该节点下
4435
+ rest.treeLoaded = true
4436
+ if (treeExpandLazyLoadedMaps[rowid]) {
4437
+ treeExpandLazyLoadedMaps[rowid] = null
4438
+ }
4439
+ if (!XEUtils.isArray(childRecords)) {
4440
+ childRecords = []
4441
+ }
4442
+ if (childRecords) {
4443
+ return this.loadTreeChildren(row, childRecords).then(childRows => {
4444
+ const { treeExpandedMaps } = this
4445
+ const treeTempExpandedMaps = { ...treeExpandedMaps }
4446
+ if (childRows.length && !treeTempExpandedMaps[rowid]) {
4447
+ treeTempExpandedMaps[rowid] = row
4448
+ this.treeExpandedMaps = treeTempExpandedMaps
4236
4449
  }
4450
+ // 如果当前节点已选中,则展开后子节点也被选中
4451
+ if (!checkStrictly && this.isCheckedByCheckboxRow(row)) {
4452
+ this.handleCheckedCheckboxRow(childRows, true, true)
4453
+ }
4454
+ return this.$nextTick().then(() => {
4455
+ if (transform) {
4456
+ return this.handleTableData()
4457
+ }
4458
+ })
4237
4459
  })
4238
- })
4239
- }
4240
- }).catch(() => {
4460
+ }
4461
+ }).catch(() => {
4241
4462
  // 如果响应异常,则不展开,再次点击后将重新触发懒加载
4242
- rest.treeLoaded = false
4243
- XEUtils.remove(treeLazyLoadeds, item => item === row)
4244
- }).finally(() => {
4245
- this.$nextTick().then(() => this.recalculate()).then(() => resolve())
4246
- })
4463
+ rest.treeLoaded = false
4464
+ const { treeExpandLazyLoadedMaps } = this
4465
+ if (treeExpandLazyLoadedMaps[rowid]) {
4466
+ treeExpandLazyLoadedMaps[rowid] = null
4467
+ }
4468
+ }).finally(() => {
4469
+ this.$nextTick().then(() => this.recalculate()).then(() => resolve())
4470
+ })
4471
+ } else {
4472
+ resolve()
4473
+ }
4247
4474
  })
4248
4475
  },
4249
4476
  /**
@@ -4252,14 +4479,15 @@ const Methods = {
4252
4479
  */
4253
4480
  setAllTreeExpand (expanded) {
4254
4481
  const { tableFullData, treeOpts } = this
4255
- const { lazy, children } = treeOpts
4482
+ const { lazy } = treeOpts
4483
+ const childrenField = treeOpts.children || treeOpts.childrenField
4256
4484
  const expandeds = []
4257
4485
  XEUtils.eachTree(tableFullData, row => {
4258
- const rowChildren = row[children]
4486
+ const rowChildren = row[childrenField]
4259
4487
  if (lazy || (rowChildren && rowChildren.length)) {
4260
4488
  expandeds.push(row)
4261
4489
  }
4262
- }, treeOpts)
4490
+ }, { children: childrenField })
4263
4491
  return this.setTreeExpand(expandeds, expanded)
4264
4492
  },
4265
4493
  /**
@@ -4269,8 +4497,11 @@ const Methods = {
4269
4497
  * @returns
4270
4498
  */
4271
4499
  handleBaseTreeExpand (rows, expanded) {
4272
- const { fullAllDataRowMap, tableFullData, treeExpandeds, treeOpts, treeLazyLoadeds, treeNodeColumn } = this
4273
- const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
4500
+ const { fullAllDataRowMap, tableFullData, treeExpandedMaps, treeOpts, treeExpandLazyLoadedMaps, treeNodeColumn } = this
4501
+ const { reserve, lazy, accordion, toggleMethod } = treeOpts
4502
+ const treeTempExpandedMaps = { ...treeExpandedMaps }
4503
+ const childrenField = treeOpts.children || treeOpts.childrenField
4504
+ const hasChildField = treeOpts.hasChild || treeOpts.hasChildField
4274
4505
  const result = []
4275
4506
  const columnIndex = this.getColumnIndex(treeNodeColumn)
4276
4507
  const $columnIndex = this.getVMColumnIndex(treeNodeColumn)
@@ -4278,32 +4509,44 @@ const Methods = {
4278
4509
  if (accordion) {
4279
4510
  validRows = validRows.length ? [validRows[validRows.length - 1]] : []
4280
4511
  // 同一级只能展开一个
4281
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
4512
+ const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], { children: childrenField })
4282
4513
  if (matchObj) {
4283
- XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
4514
+ matchObj.items.forEach(item => {
4515
+ const rowid = getRowid(this, item)
4516
+ if (treeTempExpandedMaps[rowid]) {
4517
+ delete treeTempExpandedMaps[rowid]
4518
+ }
4519
+ })
4284
4520
  }
4285
4521
  }
4286
4522
  if (expanded) {
4287
4523
  validRows.forEach(row => {
4288
- if (treeExpandeds.indexOf(row) === -1) {
4524
+ const rowid = getRowid(this, row)
4525
+ if (!treeTempExpandedMaps[rowid]) {
4289
4526
  const rest = fullAllDataRowMap.get(row)
4290
- const isLoad = lazy && row[hasChild] && !rest.treeLoaded && treeLazyLoadeds.indexOf(row) === -1
4527
+ const isLoad = lazy && row[hasChildField] && !rest.treeLoaded && !treeExpandLazyLoadedMaps[rowid]
4291
4528
  // 是否使用懒加载
4292
4529
  if (isLoad) {
4293
4530
  result.push(this.handleAsyncTreeExpandChilds(row))
4294
4531
  } else {
4295
- if (row[children] && row[children].length) {
4296
- treeExpandeds.push(row)
4532
+ if (row[childrenField] && row[childrenField].length) {
4533
+ treeTempExpandedMaps[rowid] = row
4297
4534
  }
4298
4535
  }
4299
4536
  }
4300
4537
  })
4301
4538
  } else {
4302
- XEUtils.remove(treeExpandeds, row => validRows.indexOf(row) > -1)
4539
+ validRows.forEach(item => {
4540
+ const rowid = getRowid(this, item)
4541
+ if (treeTempExpandedMaps[rowid]) {
4542
+ delete treeTempExpandedMaps[rowid]
4543
+ }
4544
+ })
4303
4545
  }
4304
4546
  if (reserve) {
4305
4547
  validRows.forEach(row => this.handleTreeExpandReserve(row, expanded))
4306
4548
  }
4549
+ this.treeExpandedMaps = treeTempExpandedMaps
4307
4550
  return Promise.all(result).then(this.recalculate)
4308
4551
  },
4309
4552
  /**
@@ -4350,18 +4593,20 @@ const Methods = {
4350
4593
  * @param {Row} row 行对象
4351
4594
  */
4352
4595
  isTreeExpandByRow (row) {
4353
- return this.treeExpandeds.indexOf(row) > -1
4596
+ const { treeExpandedMaps } = this
4597
+ return !!treeExpandedMaps[getRowid(this, row)]
4354
4598
  },
4355
4599
  /**
4356
4600
  * 手动清空树形节点的展开状态,数据会恢复成未展开的状态
4357
4601
  */
4358
4602
  clearTreeExpand () {
4359
- const { treeOpts, treeExpandeds, tableFullData } = this
4603
+ const { treeOpts, tableFullData } = this
4360
4604
  const { transform, reserve } = treeOpts
4361
- const isExists = treeExpandeds.length
4362
- this.treeExpandeds = []
4605
+ const childrenField = treeOpts.children || treeOpts.childrenField
4606
+ const expList = this.getTreeExpandRecords()
4607
+ this.treeExpandedMaps = {}
4363
4608
  if (reserve) {
4364
- XEUtils.eachTree(tableFullData, row => this.handleTreeExpandReserve(row, false), treeOpts)
4609
+ XEUtils.eachTree(tableFullData, row => this.handleTreeExpandReserve(row, false), { children: childrenField })
4365
4610
  }
4366
4611
  return this.handleTableData().then(() => {
4367
4612
  if (transform) {
@@ -4369,7 +4614,7 @@ const Methods = {
4369
4614
  return this.handleTableData()
4370
4615
  }
4371
4616
  }).then(() => {
4372
- if (isExists) {
4617
+ if (expList.length) {
4373
4618
  this.recalculate()
4374
4619
  }
4375
4620
  })
@@ -4638,9 +4883,10 @@ const Methods = {
4638
4883
  */
4639
4884
  scrollToTreeRow (row) {
4640
4885
  const { tableFullData, treeConfig, treeOpts } = this
4886
+ const childrenField = treeOpts.children || treeOpts.childrenField
4641
4887
  const rests = []
4642
4888
  if (treeConfig) {
4643
- const matchObj = XEUtils.findTree(tableFullData, item => item === row, treeOpts)
4889
+ const matchObj = XEUtils.findTree(tableFullData, item => item === row, { children: childrenField })
4644
4890
  if (matchObj) {
4645
4891
  const nodes = matchObj.nodes
4646
4892
  nodes.forEach((row, index) => {
@@ -4865,10 +5111,10 @@ const Methods = {
4865
5111
  const formatParams = { cellValue, row, rowIndex: this.getRowIndex(row), column, columnIndex: this.getColumnIndex(column) }
4866
5112
  if (XEUtils.isString(formatter)) {
4867
5113
  const gFormatOpts = formats.get(formatter)
4868
- cellLabel = gFormatOpts && gFormatOpts.formatMethod ? gFormatOpts.formatMethod(formatParams) : ''
5114
+ cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams) : ''
4869
5115
  } else if (XEUtils.isArray(formatter)) {
4870
5116
  const gFormatOpts = formats.get(formatter[0])
4871
- cellLabel = gFormatOpts && gFormatOpts.formatMethod ? gFormatOpts.formatMethod(formatParams, ...formatter.slice(1)) : ''
5117
+ cellLabel = gFormatOpts && gFormatOpts.cellFormatMethod ? gFormatOpts.cellFormatMethod(formatParams, ...formatter.slice(1)) : ''
4872
5118
  } else {
4873
5119
  cellLabel = formatter(formatParams)
4874
5120
  }
@@ -4900,7 +5146,7 @@ const Methods = {
4900
5146
  }
4901
5147
 
4902
5148
  // Module methods
4903
- const funcs = 'setFilter,openFilter,clearFilter,getCheckedFilters,closeMenu,setActiveCellArea,getActiveCellArea,getCellAreas,clearCellAreas,copyCellArea,cutCellArea,pasteCellArea,getCopyCellArea,getCopyCellAreas,clearCopyCellArea,setCellAreas,openFind,openReplace,closeFNR,getSelectedCell,clearSelected,insert,insertAt,remove,removeCheckboxRow,removeRadioRow,removeCurrentRow,getRecordset,getInsertRecords,getRemoveRecords,getUpdateRecords,clearEdit,clearActived,getEditRecord,getActiveRecord,isEditByRow,isActiveByRow,setEditRow,setActiveRow,setEditCell,setActiveCell,setSelectCell,clearValidate,fullValidate,validate,openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',')
5149
+ const funcs = 'setFilter,openFilter,clearFilter,getCheckedFilters,closeMenu,setActiveCellArea,getActiveCellArea,getCellAreas,clearCellAreas,copyCellArea,cutCellArea,pasteCellArea,getCopyCellArea,getCopyCellAreas,clearCopyCellArea,setCellAreas,openFind,openReplace,closeFNR,getSelectedCell,clearSelected,insert,insertAt,insertNextAt,remove,removeCheckboxRow,removeRadioRow,removeCurrentRow,getRecordset,getInsertRecords,getRemoveRecords,getUpdateRecords,clearEdit,clearActived,getEditRecord,getActiveRecord,isEditByRow,isActiveByRow,setEditRow,setActiveRow,setEditCell,setActiveCell,setSelectCell,clearValidate,fullValidate,validate,openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',')
4904
5150
 
4905
5151
  funcs.forEach(name => {
4906
5152
  Methods[name] = function (...args) {