vxe-table 3.3.14 → 3.4.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 (124) hide show
  1. package/helper/vetur/attributes.json +12 -200
  2. package/helper/vetur/tags.json +3 -65
  3. package/lib/button/index.min.js +1 -1
  4. package/lib/checkbox/index.min.js +1 -1
  5. package/lib/checkbox-group/index.min.js +1 -1
  6. package/lib/colgroup/index.min.js +1 -1
  7. package/lib/column/index.min.js +1 -1
  8. package/lib/edit/index.min.js +1 -1
  9. package/lib/edit/src/mixin.js +3 -3
  10. package/lib/edit/src/mixin.min.js +1 -1
  11. package/lib/export/index.js +7 -7
  12. package/lib/export/index.min.js +1 -1
  13. package/lib/export/src/mixin.js +48 -5
  14. package/lib/export/src/mixin.min.js +1 -1
  15. package/lib/filter/index.min.js +1 -1
  16. package/lib/filter/src/mixin.js +8 -2
  17. package/lib/filter/src/mixin.min.js +1 -1
  18. package/lib/footer/index.min.js +1 -1
  19. package/lib/form/index.min.js +1 -1
  20. package/lib/form/src/form.js +22 -7
  21. package/lib/form/src/form.min.js +1 -1
  22. package/lib/form/src/render.js +4 -4
  23. package/lib/form/src/render.min.js +1 -1
  24. package/lib/form/src/util.js +3 -3
  25. package/lib/form/src/util.min.js +1 -1
  26. package/lib/form-gather/index.min.js +1 -1
  27. package/lib/form-item/index.min.js +1 -1
  28. package/lib/grid/index.min.js +1 -1
  29. package/lib/grid/src/grid.js +58 -2
  30. package/lib/grid/src/grid.min.js +1 -1
  31. package/lib/header/index.min.js +1 -1
  32. package/lib/header/src/header.js +3 -2
  33. package/lib/header/src/header.min.js +1 -1
  34. package/lib/header/src/util.js +1 -1
  35. package/lib/header/src/util.min.js +1 -1
  36. package/lib/header/style/style.css +3 -10
  37. package/lib/header/style/style.min.css +1 -1
  38. package/lib/icon/index.min.js +1 -1
  39. package/lib/index.common.js +2 -2
  40. package/lib/index.common.min.js +1 -1
  41. package/lib/index.css +1 -1
  42. package/lib/index.umd.js +1945 -913
  43. package/lib/index.umd.min.js +1 -1
  44. package/lib/input/index.min.js +1 -1
  45. package/lib/input/src/input.js +1 -1
  46. package/lib/input/src/input.min.js +1 -1
  47. package/lib/keyboard/index.min.js +1 -1
  48. package/lib/keyboard/src/mixin.min.js +1 -1
  49. package/lib/list/index.min.js +1 -1
  50. package/lib/menu/index.min.js +1 -1
  51. package/lib/modal/index.js +3 -3
  52. package/lib/modal/index.min.js +1 -1
  53. package/lib/modal/src/modal.js +2 -2
  54. package/lib/modal/src/modal.min.js +1 -1
  55. package/lib/optgroup/index.min.js +1 -1
  56. package/lib/option/index.min.js +1 -1
  57. package/lib/pager/index.min.js +1 -1
  58. package/lib/pager/src/pager.js +1 -1
  59. package/lib/pulldown/index.min.js +1 -1
  60. package/lib/radio/index.min.js +1 -1
  61. package/lib/radio-button/index.min.js +1 -1
  62. package/lib/radio-group/index.min.js +1 -1
  63. package/lib/select/index.min.js +1 -1
  64. package/lib/select/src/select.js +7 -7
  65. package/lib/select/src/select.min.js +1 -1
  66. package/lib/select/src/util.js +3 -3
  67. package/lib/select/src/util.min.js +1 -1
  68. package/lib/style.css +1 -1
  69. package/lib/style.min.css +1 -1
  70. package/lib/switch/index.min.js +1 -1
  71. package/lib/table/index.min.js +1 -1
  72. package/lib/table/src/body.js +16 -11
  73. package/lib/table/src/body.min.js +1 -1
  74. package/lib/table/src/cell.js +1 -1
  75. package/lib/table/src/cell.min.js +1 -1
  76. package/lib/table/src/methods.js +310 -137
  77. package/lib/table/src/methods.min.js +1 -1
  78. package/lib/table/src/table.js +12 -2
  79. package/lib/table/src/table.min.js +1 -1
  80. package/lib/table/src/util.js +7 -7
  81. package/lib/table/src/util.min.js +1 -1
  82. package/lib/table/style/style.css +13 -10
  83. package/lib/table/style/style.min.css +1 -1
  84. package/lib/textarea/index.min.js +1 -1
  85. package/lib/toolbar/index.min.js +1 -1
  86. package/lib/tools/index.js +2 -2
  87. package/lib/tools/index.min.js +1 -1
  88. package/lib/tools/src/dom.js +2 -2
  89. package/lib/tools/src/dom.min.js +1 -1
  90. package/lib/tools/src/event.js +1 -1
  91. package/lib/tools/src/event.min.js +1 -1
  92. package/lib/tools/src/utils.js +3 -3
  93. package/lib/tools/src/utils.min.js +1 -1
  94. package/lib/tooltip/index.min.js +1 -1
  95. package/lib/v-x-e-table/index.js +5 -3
  96. package/lib/v-x-e-table/index.min.js +1 -1
  97. package/lib/v-x-e-table/src/conf.js +3 -1
  98. package/lib/v-x-e-table/src/conf.min.js +1 -1
  99. package/lib/v-x-e-table/src/renderer.js +4 -4
  100. package/lib/v-x-e-table/src/renderer.min.js +1 -1
  101. package/lib/v-x-e-table/src/store.min.js +1 -1
  102. package/lib/validator/index.min.js +1 -1
  103. package/lib/validator/src/mixin.js +9 -4
  104. package/lib/validator/src/mixin.min.js +1 -1
  105. package/package.json +5 -6
  106. package/packages/edit/src/mixin.js +2 -2
  107. package/packages/export/src/mixin.js +38 -1
  108. package/packages/filter/src/mixin.js +2 -2
  109. package/packages/form/src/form.js +10 -6
  110. package/packages/form/src/render.js +4 -4
  111. package/packages/grid/src/grid.js +48 -0
  112. package/packages/header/src/header.js +2 -2
  113. package/packages/select/src/select.js +5 -5
  114. package/packages/table/src/body.js +15 -10
  115. package/packages/table/src/methods.js +192 -66
  116. package/packages/table/src/table.js +11 -2
  117. package/packages/v-x-e-table/src/conf.js +3 -1
  118. package/packages/v-x-e-table/src/renderer.js +4 -4
  119. package/packages/validator/src/mixin.js +8 -4
  120. package/styles/button.scss +4 -4
  121. package/styles/header.scss +9 -12
  122. package/styles/modal.scss +4 -4
  123. package/styles/table.scss +13 -7
  124. package/styles/variable.scss +1 -1
@@ -306,32 +306,67 @@ const Methods = {
306
306
  this.tableData = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0)
307
307
  return this.$nextTick()
308
308
  },
309
+ updateScrollYStatus (fullData) {
310
+ const { treeConfig, treeOpts, sYOpts } = this
311
+ const { transform } = treeOpts
312
+ const scrollYLoad = (transform || !treeConfig) && !!sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < fullData.length
313
+ this.scrollYLoad = scrollYLoad
314
+ return scrollYLoad
315
+ },
309
316
  /**
310
317
  * 加载表格数据
311
318
  * @param {Array} datas 数据
312
319
  */
313
320
  loadTableData (datas) {
314
- const { keepSource, treeConfig, editStore, sYOpts, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop, scrollYLoad: oldScrollYLoad } = this
315
- const tableFullData = datas ? datas.slice(0) : []
316
- const scrollYLoad = !treeConfig && sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < tableFullData.length
321
+ const { keepSource, treeConfig, treeOpts, editStore, scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop, scrollYLoad: oldScrollYLoad } = this
322
+ let treeData = []
323
+ let fullData = datas ? datas.slice(0) : []
324
+ if (treeConfig) {
325
+ // 树结构自动转换
326
+ if (treeOpts.transform) {
327
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
328
+ if (!treeOpts.rowtKey) {
329
+ UtilTools.error('vxe.error.reqProp', ['table.tree-config.rowtKey'])
330
+ }
331
+ if (!treeOpts.parentKey) {
332
+ UtilTools.error('vxe.error.reqProp', ['table.tree-config.parentKey'])
333
+ }
334
+ if (!treeOpts.children) {
335
+ UtilTools.error('vxe.error.reqProp', ['tree-config.children'])
336
+ }
337
+ fullData.forEach(row => {
338
+ if (row[treeOpts.children] && row[treeOpts.children].length) {
339
+ UtilTools.warn('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
340
+ }
341
+ })
342
+ }
343
+ treeData = XEUtils.toArrayTree(fullData, { key: treeOpts.rowtKey, parentKey: treeOpts.parentKey, children: treeOpts.children })
344
+ fullData = treeData.slice(0)
345
+ } else {
346
+ treeData = fullData.slice(0)
347
+ }
348
+ }
317
349
  scrollYStore.startIndex = 0
318
350
  scrollYStore.endIndex = 1
319
351
  scrollXStore.startIndex = 0
320
352
  scrollXStore.endIndex = 1
321
353
  editStore.insertList = []
322
354
  editStore.removeList = []
355
+ const sYLoad = this.updateScrollYStatus(fullData)
356
+ this.scrollYLoad = sYLoad
323
357
  // 全量数据
324
- this.tableFullData = tableFullData
358
+ this.tableFullData = fullData
359
+ this.treeFullData = treeData
325
360
  // 缓存数据
326
- this.updateCache(true)
361
+ this.cacheRowMap(true)
327
362
  // 原始数据
328
363
  this.tableSynchData = datas
364
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
329
365
  if (keepSource) {
330
- this.tableSourceData = XEUtils.clone(tableFullData, true)
366
+ this.tableSourceData = XEUtils.clone(fullData, true)
331
367
  }
332
- this.scrollYLoad = scrollYLoad
333
368
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
334
- if (scrollYLoad) {
369
+ if (sYLoad) {
335
370
  if (!(this.height || this.maxHeight)) {
336
371
  UtilTools.error('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}'])
337
372
  }
@@ -357,8 +392,8 @@ const Methods = {
357
392
  }).then(() => {
358
393
  this.computeScrollLoad()
359
394
  }).then(() => {
360
- // 是否加载了数据
361
- if (scrollYLoad) {
395
+ // 是否启用了虚拟滚动
396
+ if (sYLoad) {
362
397
  scrollYStore.endIndex = scrollYStore.visibleSize
363
398
  }
364
399
  this.handleReserveStatus()
@@ -368,7 +403,7 @@ const Methods = {
368
403
  .then(() => this.recalculate())
369
404
  .then(() => {
370
405
  // 是否变更虚拟滚动
371
- if (oldScrollYLoad === scrollYLoad) {
406
+ if (oldScrollYLoad === sYLoad) {
372
407
  restoreScrollLocation(this, lastScrollLeft, lastScrollTop).then(resolve)
373
408
  } else {
374
409
  setTimeout(() => restoreScrollLocation(this, lastScrollLeft, lastScrollTop).then(resolve))
@@ -435,7 +470,7 @@ const Methods = {
435
470
  tableSourceData[rowIndex] = record
436
471
  XEUtils.clear(row, undefined)
437
472
  Object.assign(row, this.defineField(Object.assign({}, record)))
438
- this.updateCache(true)
473
+ this.cacheRowMap(true)
439
474
  } else {
440
475
  XEUtils.destructuring(oRow, XEUtils.clone(row, true))
441
476
  }
@@ -498,12 +533,12 @@ const Methods = {
498
533
  * 更新数据行的 Map
499
534
  * 牺牲数据组装的耗时,用来换取使用过程中的流畅
500
535
  */
501
- updateCache (source) {
536
+ cacheRowMap (source) {
502
537
  const { treeConfig, treeOpts, tableFullData, fullDataRowMap, fullAllDataRowMap } = this
503
538
  let { fullDataRowIdData, fullAllDataRowIdData } = this
504
539
  const rowkey = getRowkey(this)
505
540
  const isLazy = treeConfig && treeOpts.lazy
506
- const handleCache = (row, index, items, path, parent) => {
541
+ const handleCache = (row, index, items, path, parent, nodes) => {
507
542
  let rowid = getRowid(this, row)
508
543
  if (eqEmptyValue(rowid)) {
509
544
  rowid = getRowUniqueId()
@@ -512,7 +547,7 @@ const Methods = {
512
547
  if (isLazy && row[treeOpts.hasChild] && XEUtils.isUndefined(row[treeOpts.children])) {
513
548
  row[treeOpts.children] = null
514
549
  }
515
- const rest = { row, rowid, index: treeConfig && parent ? -1 : index, items, parent }
550
+ const rest = { row, rowid, index: treeConfig && parent ? -1 : index, items, parent, level: nodes ? nodes.length - 1 : 0 }
516
551
  if (source) {
517
552
  fullDataRowIdData[rowid] = rest
518
553
  fullDataRowMap.set(row, rest)
@@ -532,10 +567,12 @@ const Methods = {
532
567
  tableFullData.forEach(handleCache)
533
568
  }
534
569
  },
535
- loadChildren (row, childRecords) {
570
+ loadTreeChildren (row, childRecords) {
571
+ const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData } = this
572
+ const { children } = treeOpts
573
+ const rest = fullAllDataRowIdData[getRowid(this, row)]
574
+ const parentLevel = rest ? rest.level : 0
536
575
  return this.createData(childRecords).then((rows) => {
537
- const { keepSource, tableSourceData, treeOpts, fullDataRowIdData, fullDataRowMap, fullAllDataRowMap, fullAllDataRowIdData } = this
538
- const { children } = treeOpts
539
576
  if (keepSource) {
540
577
  const rowid = getRowid(this, row)
541
578
  const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid(this, item), treeOpts)
@@ -543,9 +580,9 @@ const Methods = {
543
580
  matchObj.item[children] = XEUtils.clone(rows, true)
544
581
  }
545
582
  }
546
- XEUtils.eachTree(rows, (childRow, index, items, path, parent) => {
583
+ XEUtils.eachTree(rows, (childRow, index, items, path, parent, nodes) => {
547
584
  const rowid = getRowid(this, childRow)
548
- const rest = { row: childRow, rowid, index: -1, items, parent }
585
+ const rest = { row: childRow, rowid, index: -1, items, parent, level: parentLevel + nodes.length }
549
586
  fullDataRowIdData[rowid] = rest
550
587
  fullDataRowMap.set(childRow, rest)
551
588
  fullAllDataRowIdData[rowid] = rest
@@ -910,6 +947,13 @@ const Methods = {
910
947
  isInsertByRow (row) {
911
948
  return this.editStore.insertList.indexOf(row) > -1
912
949
  },
950
+ /**
951
+ * 删除所有新增的临时数据
952
+ * @returns
953
+ */
954
+ removeInsertRow () {
955
+ return this.remove(this.editStore.insertList)
956
+ },
913
957
  /**
914
958
  * 检查行或列数据是否发生改变
915
959
  * @param {Row} row 行对象
@@ -1053,6 +1097,7 @@ const Methods = {
1053
1097
  const { filterMethod, filterRender } = column
1054
1098
  const compConf = filterRender ? VXETable.renderer.get(filterRender.name) : null
1055
1099
  const compFilterMethod = compConf && compConf.renderFilter ? compConf.filterMethod : null
1100
+ const defaultFilterMethod = compConf ? compConf.defaultFilterMethod : null
1056
1101
  const cellValue = UtilTools.getCellValue(row, column)
1057
1102
  if (filterMethod) {
1058
1103
  return itemList.some((item) => filterMethod({ value: item.value, option: item, cellValue, row, column, $table: this }))
@@ -1060,6 +1105,8 @@ const Methods = {
1060
1105
  return itemList.some((item) => compFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: this }))
1061
1106
  } else if (allFilterMethod) {
1062
1107
  return allFilterMethod({ options: itemList, values: valueList, cellValue, row, column })
1108
+ } else if (defaultFilterMethod) {
1109
+ return itemList.some((item) => defaultFilterMethod({ value: item.value, option: item, cellValue, row, column, $table: this }))
1063
1110
  }
1064
1111
  return valueList.indexOf(XEUtils.get(row, column.property)) > -1
1065
1112
  }
@@ -2354,10 +2401,10 @@ const Methods = {
2354
2401
  triggerHeaderHelpEvent (evnt, params) {
2355
2402
  const { column } = params
2356
2403
  const { titleHelp } = column
2357
- if (titleHelp.message) {
2404
+ if (titleHelp.content || titleHelp.message) {
2358
2405
  const { $refs, tooltipStore } = this
2359
2406
  const tooltip = $refs.tooltip
2360
- const content = UtilTools.getFuncText(titleHelp.message)
2407
+ const content = UtilTools.getFuncText(titleHelp.content || titleHelp.message)
2361
2408
  this.handleTargetEnterEvent()
2362
2409
  tooltipStore.visible = true
2363
2410
  if (tooltip) {
@@ -3394,12 +3441,17 @@ const Methods = {
3394
3441
  * @param {Event} evnt 事件
3395
3442
  */
3396
3443
  closeFilter () {
3397
- Object.assign(this.filterStore, {
3444
+ const { filterStore } = this
3445
+ const { column, visible } = filterStore
3446
+ Object.assign(filterStore, {
3398
3447
  isAllSelected: false,
3399
3448
  isIndeterminate: false,
3400
3449
  options: [],
3401
3450
  visible: false
3402
3451
  })
3452
+ if (visible) {
3453
+ this.emitEvent('filter-visible', { column, property: column.property, filterList: this.getCheckedFilters(), visible: false }, null)
3454
+ }
3403
3455
  return this.$nextTick()
3404
3456
  },
3405
3457
  /**
@@ -3432,10 +3484,10 @@ const Methods = {
3432
3484
  return this.$nextTick()
3433
3485
  },
3434
3486
  /**
3435
- * 重新加载展开行的内容
3487
+ * 重新懒加载展开行,并展开内容
3436
3488
  * @param {Row} row 行对象
3437
3489
  */
3438
- reloadExpandContent (row) {
3490
+ lazyExpandContent (row) {
3439
3491
  const { expandOpts, expandLazyLoadeds } = this
3440
3492
  const { lazy } = expandOpts
3441
3493
  if (lazy && expandLazyLoadeds.indexOf(row) === -1) {
@@ -3444,6 +3496,13 @@ const Methods = {
3444
3496
  }
3445
3497
  return this.$nextTick()
3446
3498
  },
3499
+ reloadExpandContent (row) {
3500
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3501
+ UtilTools.warn('vxe.error.delFunc', ['reloadExpandContent', 'lazyExpandContent'])
3502
+ }
3503
+ // 即将废弃
3504
+ return this.lazyExpandContent(row)
3505
+ },
3447
3506
  /**
3448
3507
  * 展开行事件
3449
3508
  */
@@ -3624,18 +3683,32 @@ const Methods = {
3624
3683
  return this.$nextTick()
3625
3684
  },
3626
3685
  /**
3627
- * 重新加载树的子节点
3686
+ * 重新懒加载树节点,并展开该节点
3628
3687
  * @param {Row} row 行对象
3629
3688
  */
3630
- reloadTreeChilds (row) {
3689
+ lazyTreeChildren (row) {
3631
3690
  const { treeOpts, treeLazyLoadeds } = this
3632
- const { lazy, hasChild } = treeOpts
3691
+ const { transform, lazy, hasChild } = treeOpts
3633
3692
  if (lazy && row[hasChild] && treeLazyLoadeds.indexOf(row) === -1) {
3634
- this.clearTreeExpandLoaded(row)
3635
- .then(() => this.handleAsyncTreeExpandChilds(row))
3693
+ this.clearTreeExpandLoaded(row).then(() => {
3694
+ return this.handleAsyncTreeExpandChilds(row)
3695
+ }).then(() => {
3696
+ if (transform) {
3697
+ return this.updateVirtualTreeData()
3698
+ }
3699
+ }).then(() => {
3700
+ return this.recalculate()
3701
+ })
3636
3702
  }
3637
3703
  return this.$nextTick()
3638
3704
  },
3705
+ reloadTreeChilds (row) {
3706
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3707
+ UtilTools.warn('vxe.error.delFunc', ['reloadTreeChilds', 'lazyTreeChildren'])
3708
+ }
3709
+ // 即将废弃
3710
+ return this.lazyTreeChildren(row)
3711
+ },
3639
3712
  /**
3640
3713
  * 展开树节点事件
3641
3714
  */
@@ -3693,7 +3766,7 @@ const Methods = {
3693
3766
  childRecords = []
3694
3767
  }
3695
3768
  if (childRecords) {
3696
- this.loadChildren(row, childRecords).then(childRows => {
3769
+ this.loadTreeChildren(row, childRecords).then(childRows => {
3697
3770
  if (childRows.length && treeExpandeds.indexOf(row) === -1) {
3698
3771
  treeExpandeds.push(row)
3699
3772
  }
@@ -3723,6 +3796,78 @@ const Methods = {
3723
3796
  }, treeOpts)
3724
3797
  return this.setTreeExpand(expandeds, expanded)
3725
3798
  },
3799
+ /**
3800
+ * 默认,展开与收起树节点
3801
+ * @param rows
3802
+ * @param expanded
3803
+ * @returns
3804
+ */
3805
+ handleBaseTreeExpand (rows, expanded) {
3806
+ const { fullAllDataRowMap, tableFullData, treeExpandeds, treeOpts, treeLazyLoadeds, treeNodeColumn } = this
3807
+ const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3808
+ const result = []
3809
+ const columnIndex = this.getColumnIndex(treeNodeColumn)
3810
+ const $columnIndex = this.getVMColumnIndex(treeNodeColumn)
3811
+ let validRows = toggleMethod ? rows.filter(row => toggleMethod({ expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3812
+ if (accordion) {
3813
+ validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3814
+ // 同一级只能展开一个
3815
+ const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3816
+ if (matchObj) {
3817
+ XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3818
+ }
3819
+ }
3820
+ if (expanded) {
3821
+ validRows.forEach(row => {
3822
+ if (treeExpandeds.indexOf(row) === -1) {
3823
+ const rest = fullAllDataRowMap.get(row)
3824
+ const isLoad = lazy && row[hasChild] && !rest.treeLoaded && treeLazyLoadeds.indexOf(row) === -1
3825
+ // 是否使用懒加载
3826
+ if (isLoad) {
3827
+ result.push(this.handleAsyncTreeExpandChilds(row))
3828
+ } else {
3829
+ if (row[children] && row[children].length) {
3830
+ treeExpandeds.push(row)
3831
+ }
3832
+ }
3833
+ }
3834
+ })
3835
+ } else {
3836
+ XEUtils.remove(treeExpandeds, row => validRows.indexOf(row) > -1)
3837
+ }
3838
+ if (reserve) {
3839
+ validRows.forEach(row => this.handleTreeExpandReserve(row, expanded))
3840
+ }
3841
+ return Promise.all(result).then(this.recalculate)
3842
+ },
3843
+ updateVirtualTreeData () {
3844
+ const { scrollYLoad: oldScrollYLoad, treeExpandeds, treeOpts, treeFullData } = this
3845
+ const fullData = []
3846
+ XEUtils.eachTree(treeFullData, (row, index, items, path, parent) => {
3847
+ if (!parent || treeExpandeds.indexOf(parent) > -1) {
3848
+ fullData.push(row)
3849
+ }
3850
+ }, treeOpts)
3851
+ const scrollYLoad = this.updateScrollYStatus(fullData)
3852
+ this.tableFullData = scrollYLoad ? fullData : treeFullData
3853
+ if (scrollYLoad || oldScrollYLoad !== scrollYLoad) {
3854
+ return this.handleTableData(true).then(() => this.recalculate())
3855
+ }
3856
+ return this.$nextTick()
3857
+ },
3858
+ /**
3859
+ * 虚拟树的展开与收起
3860
+ * @param rows
3861
+ * @param expanded
3862
+ * @returns
3863
+ */
3864
+ handleVirtualTreeExpand (rows, expanded) {
3865
+ return this.handleBaseTreeExpand(rows, expanded).then(() => {
3866
+ return this.updateVirtualTreeData()
3867
+ }).then(() => {
3868
+ return this.recalculate()
3869
+ })
3870
+ },
3726
3871
  /**
3727
3872
  * 设置展开树形节点,二个参数设置这一行展开与否
3728
3873
  * 支持单行
@@ -3731,47 +3876,19 @@ const Methods = {
3731
3876
  * @param {Boolean} expanded 是否展开
3732
3877
  */
3733
3878
  setTreeExpand (rows, expanded) {
3734
- const { fullAllDataRowMap, tableFullData, treeExpandeds, treeOpts, treeLazyLoadeds, treeNodeColumn } = this
3735
- const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3736
- const result = []
3737
- const columnIndex = this.getColumnIndex(treeNodeColumn)
3738
- const $columnIndex = this.getVMColumnIndex(treeNodeColumn)
3879
+ const { treeOpts } = this
3880
+ const { transform } = treeOpts
3739
3881
  if (rows) {
3740
3882
  if (!XEUtils.isArray(rows)) {
3741
3883
  rows = [rows]
3742
3884
  }
3743
3885
  if (rows.length) {
3744
- let validRows = toggleMethod ? rows.filter(row => toggleMethod({ expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3745
- if (accordion) {
3746
- validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3747
- // 同一级只能展开一个
3748
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3749
- if (matchObj) {
3750
- XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3751
- }
3752
- }
3753
- if (expanded) {
3754
- validRows.forEach(row => {
3755
- if (treeExpandeds.indexOf(row) === -1) {
3756
- const rest = fullAllDataRowMap.get(row)
3757
- const isLoad = lazy && row[hasChild] && !rest.treeLoaded && treeLazyLoadeds.indexOf(row) === -1
3758
- // 是否使用懒加载
3759
- if (isLoad) {
3760
- result.push(this.handleAsyncTreeExpandChilds(row))
3761
- } else {
3762
- if (row[children] && row[children].length) {
3763
- treeExpandeds.push(row)
3764
- }
3765
- }
3766
- }
3767
- })
3886
+ // 如果为虚拟树
3887
+ if (transform) {
3888
+ return this.handleVirtualTreeExpand(rows, expanded)
3768
3889
  } else {
3769
- XEUtils.remove(treeExpandeds, row => validRows.indexOf(row) > -1)
3770
- }
3771
- if (reserve) {
3772
- validRows.forEach(row => this.handleTreeExpandReserve(row, expanded))
3890
+ return this.handleBaseTreeExpand(rows, expanded)
3773
3891
  }
3774
- return Promise.all(result).then(this.recalculate)
3775
3892
  }
3776
3893
  }
3777
3894
  return this.$nextTick()
@@ -3794,7 +3911,7 @@ const Methods = {
3794
3911
  if (reserve) {
3795
3912
  XEUtils.eachTree(tableFullData, row => this.handleTreeExpandReserve(row, false), treeOpts)
3796
3913
  }
3797
- return this.$nextTick().then(() => {
3914
+ return this.updateVirtualTreeData().then(() => {
3798
3915
  if (isExists) {
3799
3916
  this.recalculate()
3800
3917
  }
@@ -4307,6 +4424,15 @@ const funcs = 'setFilter,clearFilter,getCheckedFilters,closeMenu,setActiveCellAr
4307
4424
 
4308
4425
  funcs.forEach(name => {
4309
4426
  Methods[name] = function (...args) {
4427
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
4428
+ if (!this[`_${name}`]) {
4429
+ if ('openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',').includes(name)) {
4430
+ UtilTools.error('vxe.error.reqModule', ['Export'])
4431
+ } else if ('clearValidate,fullValidate,validate'.split(',').includes(name)) {
4432
+ UtilTools.error('vxe.error.reqModule', ['Validator'])
4433
+ }
4434
+ }
4435
+ }
4310
4436
  return this[`_${name}`] ? this[`_${name}`](...args) : null
4311
4437
  }
4312
4438
  })
@@ -179,8 +179,11 @@ export default {
179
179
  autoResize: { type: Boolean, default: () => GlobalConfig.table.autoResize },
180
180
  // 是否自动根据状态属性去更新响应式表格宽高
181
181
  syncResize: [Boolean, String, Number],
182
- // 设置列的默认参数,仅对部分支持的属性有效
182
+ // 列配置信息
183
183
  columnConfig: Object,
184
+ // 行配置信息
185
+ rowConfig: Object,
186
+ // 列调整配置项
184
187
  resizableConfig: Object,
185
188
  // 序号配置项
186
189
  seqConfig: Object,
@@ -453,7 +456,10 @@ export default {
453
456
  }
454
457
  },
455
458
  columnOpts () {
456
- return Object.assign({}, this.columnConfig)
459
+ return Object.assign({}, GlobalConfig.table.columnConfig, this.columnConfig)
460
+ },
461
+ rowOpts () {
462
+ return Object.assign({}, GlobalConfig.table.rowConfig, this.rowConfig)
457
463
  },
458
464
  resizableOpts () {
459
465
  return Object.assign({}, GlobalConfig.table.resizableConfig, this.resizableConfig)
@@ -780,6 +786,9 @@ export default {
780
786
  if (this.treeConfig && this.checkboxOpts.range) {
781
787
  UtilTools.error('vxe.error.noTree', ['checkbox-config.range'])
782
788
  }
789
+ if (this.rowOpts.height && !this.showOverflow) {
790
+ UtilTools.warn('vxe.error.notProp', ['table.show-overflow'])
791
+ }
783
792
  if (!this.handleUpdateCellAreas) {
784
793
  if (this.clipConfig) {
785
794
  UtilTools.warn('vxe.error.notProp', ['clip-config'])
@@ -9,6 +9,7 @@ export default {
9
9
  table: {
10
10
  fit: true,
11
11
  showHeader: true,
12
+ animat: true,
12
13
  delayHover: 250,
13
14
  // keepSource: false,
14
15
  // showOverflow: null,
@@ -17,7 +18,6 @@ export default {
17
18
  // resizeInterval: 500,
18
19
  // size: null,
19
20
  // zIndex: null,
20
- // resizable: false,
21
21
  // autoResize: false,
22
22
  // stripe: false,
23
23
  // border: false,
@@ -63,6 +63,8 @@ export default {
63
63
  showIcon: true
64
64
  },
65
65
  treeConfig: {
66
+ rowtKey: 'id',
67
+ parentKey: 'parentId',
66
68
  children: 'children',
67
69
  hasChild: 'hasChild',
68
70
  indent: 20,
@@ -522,7 +522,7 @@ const renderMap = {
522
522
  renderEdit: nativeEditRender,
523
523
  renderDefault: nativeEditRender,
524
524
  renderFilter: nativeFilterRender,
525
- filterMethod: handleFilterMethod,
525
+ defaultFilterMethod: handleFilterMethod,
526
526
  renderItemContent: nativeItemRender
527
527
  },
528
528
  textarea: {
@@ -548,7 +548,7 @@ const renderMap = {
548
548
  renderOpts.optionGroups ? renderNativeOptgroups(h, renderOpts, params, renderNativeOptions) : renderNativeOptions(h, renderOpts.options, renderOpts, params))
549
549
  })
550
550
  },
551
- filterMethod: handleFilterMethod,
551
+ defaultFilterMethod: handleFilterMethod,
552
552
  renderItemContent (h, renderOpts, params) {
553
553
  return [
554
554
  h('select', {
@@ -586,7 +586,7 @@ const renderMap = {
586
586
  },
587
587
  renderDefault: defaultEditRender,
588
588
  renderFilter: defaultFilterRender,
589
- filterMethod: handleFilterMethod,
589
+ defaultFilterMethod: handleFilterMethod,
590
590
  renderItemContent: defaultItemRender
591
591
  },
592
592
  $textarea: {
@@ -622,7 +622,7 @@ const renderMap = {
622
622
  })
623
623
  })
624
624
  },
625
- filterMethod: handleFilterMethod,
625
+ defaultFilterMethod: handleFilterMethod,
626
626
  renderItemContent (h, renderOpts, params) {
627
627
  const { data, property } = params
628
628
  const { options, optionProps, optionGroups, optionGroupProps } = renderOpts
@@ -24,8 +24,12 @@ class Rule {
24
24
  * 获取校验不通过的消息
25
25
  * 支持国际化翻译
26
26
  */
27
+ get content () {
28
+ return UtilTools.getFuncText(this.$options.content || this.$options.message)
29
+ }
30
+
27
31
  get message () {
28
- return UtilTools.getFuncText(this.$options.message)
32
+ return this.content
29
33
  }
30
34
  }
31
35
 
@@ -245,13 +249,13 @@ export default {
245
249
  if (customValid) {
246
250
  if (XEUtils.isError(customValid)) {
247
251
  this.validRuleErr = true
248
- errorRules.push(new Rule({ type: 'custom', trigger, message: customValid.message, rule: new Rule(rule) }))
252
+ errorRules.push(new Rule({ type: 'custom', trigger, content: customValid.message, rule: new Rule(rule) }))
249
253
  } else if (customValid.catch) {
250
254
  // 如果为异步校验(注:异步校验是并发无序的)
251
255
  syncVailds.push(
252
256
  customValid.catch(e => {
253
257
  this.validRuleErr = true
254
- errorRules.push(new Rule({ type: 'custom', trigger, message: e && e.message ? e.message : rule.message, rule: new Rule(rule) }))
258
+ errorRules.push(new Rule({ type: 'custom', trigger, content: e && e.message ? e.message : (rule.content || rule.message), rule: new Rule(rule) }))
255
259
  })
256
260
  )
257
261
  }
@@ -324,7 +328,7 @@ export default {
324
328
  const { $refs, height, tableData, validOpts } = this
325
329
  const { rule, row, column, cell } = params
326
330
  const validTip = $refs.validTip
327
- const content = rule.message
331
+ const content = rule.content
328
332
  return this.$nextTick(() => {
329
333
  Object.assign(this.validStore, {
330
334
  row,
@@ -124,7 +124,7 @@ $btnThemeList: (
124
124
  line-height: 1;
125
125
  border: 1px solid $vxe-input-border-color;
126
126
  &.is--round {
127
- border-radius: $vxe-button-height-default / 2;
127
+ border-radius: $vxe-button-height-default * 0.5;
128
128
  }
129
129
  &:not(.is--round) {
130
130
  border-radius: $vxe-border-radius;
@@ -223,7 +223,7 @@ $btnThemeList: (
223
223
  min-width: $vxe-button-height-medium;
224
224
  }
225
225
  &.is--round {
226
- border-radius: $vxe-button-height-medium / 2;
226
+ border-radius: $vxe-button-height-medium * 0.5;
227
227
  }
228
228
  }
229
229
  .vxe-button--loading-icon,
@@ -239,7 +239,7 @@ $btnThemeList: (
239
239
  min-width: $vxe-button-height-small;
240
240
  }
241
241
  &.is--round {
242
- border-radius: $vxe-button-height-small / 2;
242
+ border-radius: $vxe-button-height-small * 0.5;
243
243
  }
244
244
  }
245
245
  .vxe-button--loading-icon,
@@ -255,7 +255,7 @@ $btnThemeList: (
255
255
  min-width: $vxe-button-height-mini;
256
256
  }
257
257
  &.is--round {
258
- border-radius: $vxe-button-height-mini / 2;
258
+ border-radius: $vxe-button-height-mini * 0.5;
259
259
  }
260
260
  }
261
261
  .vxe-button--loading-icon,
@@ -14,7 +14,7 @@
14
14
  /*排序*/
15
15
  .vxe-cell--sort {
16
16
  width: 1.5em;
17
- height: 1.5em;
17
+ height: 1.35em;
18
18
  vertical-align: middle;
19
19
  text-align: center;
20
20
  display: inline-block;
@@ -36,10 +36,10 @@
36
36
  }
37
37
  }
38
38
  .vxe-sort--asc-btn {
39
- top: -0.04em;
39
+ top: -0.15em;
40
40
  }
41
41
  .vxe-sort--desc-btn {
42
- bottom: -0.04em;
42
+ bottom: -0.15em;
43
43
  }
44
44
  }
45
45
 
@@ -80,12 +80,12 @@
80
80
  top: 0.2em;
81
81
  }
82
82
  }
83
- .vxe-cell--required-icon,
84
- .vxe-cell--edit-icon,
85
- .vxe-cell-help-icon,
86
- .vxe-cell--title {
87
- vertical-align: middle;
88
- }
83
+ // .vxe-cell--required-icon,
84
+ // .vxe-cell--edit-icon,
85
+ // .vxe-cell-help-icon,
86
+ // .vxe-cell--title {
87
+ // vertical-align: middle;
88
+ // }
89
89
  .vxe-cell--required-icon {
90
90
  margin-right: 0.1em;
91
91
  }
@@ -96,9 +96,6 @@
96
96
  .vxe-cell-help-icon {
97
97
  cursor: help;
98
98
  }
99
- .vxe-cell--title {
100
- line-height: 1.5;
101
- }
102
99
  .vxe-resizable {
103
100
  position: absolute;
104
101
  right: -7px;