vxe-table 4.0.30 → 4.1.1

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 (127) hide show
  1. package/README.md +1 -0
  2. package/README.zh-TW.md +1 -0
  3. package/es/button/style.css +2 -2
  4. package/es/checkbox/style.css +1 -1
  5. package/es/edit/src/hook.js +2 -2
  6. package/es/export/src/hook.js +24 -0
  7. package/es/export/src/util.js +20 -8
  8. package/es/export/style.css +1 -1
  9. package/es/filter/src/hook.js +2 -2
  10. package/es/filter/style.css +2 -2
  11. package/es/footer/src/footer.js +4 -4
  12. package/es/form/src/form.js +13 -6
  13. package/es/form/src/render.js +4 -4
  14. package/es/grid/src/grid.js +48 -1
  15. package/es/header/src/header.js +7 -5
  16. package/es/header/style.css +3 -10
  17. package/es/input/style.css +4 -4
  18. package/es/menu/style.css +1 -1
  19. package/es/modal/style.css +1 -1
  20. package/es/pager/style.css +2 -2
  21. package/es/radio/style.css +1 -1
  22. package/es/select/src/select.js +5 -5
  23. package/es/select/style.css +1 -1
  24. package/es/style.css +1 -1
  25. package/es/style.min.css +1 -1
  26. package/es/table/src/body.js +18 -14
  27. package/es/table/src/emits.js +1 -0
  28. package/es/table/src/props.js +4 -1
  29. package/es/table/src/table.js +219 -89
  30. package/es/table/style.css +15 -12
  31. package/es/toolbar/style.css +1 -1
  32. package/es/v-x-e-table/src/conf.js +2 -1
  33. package/es/v-x-e-table/src/renderer.js +4 -4
  34. package/es/validator/src/hook.js +12 -5
  35. package/helper/vetur/attributes.json +16 -204
  36. package/helper/vetur/tags.json +3 -65
  37. package/lib/button/style/style.css +2 -2
  38. package/lib/button/style/style.min.css +1 -1
  39. package/lib/checkbox/style/style.css +1 -1
  40. package/lib/checkbox/style/style.min.css +1 -1
  41. package/lib/edit/src/hook.js +2 -2
  42. package/lib/edit/src/hook.min.js +1 -1
  43. package/lib/export/src/hook.js +28 -0
  44. package/lib/export/src/hook.min.js +1 -1
  45. package/lib/export/src/util.js +21 -7
  46. package/lib/export/src/util.min.js +1 -1
  47. package/lib/export/style/style.css +1 -1
  48. package/lib/export/style/style.min.css +1 -1
  49. package/lib/filter/src/hook.js +8 -2
  50. package/lib/filter/src/hook.min.js +1 -1
  51. package/lib/filter/style/style.css +2 -2
  52. package/lib/filter/style/style.min.css +1 -1
  53. package/lib/footer/src/footer.js +4 -4
  54. package/lib/footer/src/footer.min.js +1 -1
  55. package/lib/form/src/form.js +23 -6
  56. package/lib/form/src/form.min.js +1 -1
  57. package/lib/form/src/render.js +4 -4
  58. package/lib/form/src/render.min.js +1 -1
  59. package/lib/grid/src/grid.js +56 -1
  60. package/lib/grid/src/grid.min.js +1 -1
  61. package/lib/header/src/header.js +7 -5
  62. package/lib/header/src/header.min.js +1 -1
  63. package/lib/header/style/style.css +3 -10
  64. package/lib/header/style/style.min.css +1 -1
  65. package/lib/index.umd.js +561 -186
  66. package/lib/index.umd.min.js +1 -1
  67. package/lib/input/style/style.css +4 -4
  68. package/lib/input/style/style.min.css +1 -1
  69. package/lib/menu/style/style.css +1 -1
  70. package/lib/menu/style/style.min.css +1 -1
  71. package/lib/modal/style/style.css +1 -1
  72. package/lib/modal/style/style.min.css +1 -1
  73. package/lib/pager/style/style.css +2 -2
  74. package/lib/pager/style/style.min.css +1 -1
  75. package/lib/radio/style/style.css +1 -1
  76. package/lib/radio/style/style.min.css +1 -1
  77. package/lib/select/src/select.js +5 -5
  78. package/lib/select/style/style.css +1 -1
  79. package/lib/select/style/style.min.css +1 -1
  80. package/lib/style.css +1 -1
  81. package/lib/style.min.css +1 -1
  82. package/lib/table/src/body.js +18 -14
  83. package/lib/table/src/body.min.js +1 -1
  84. package/lib/table/src/emits.js +1 -1
  85. package/lib/table/src/emits.min.js +1 -1
  86. package/lib/table/src/props.js +4 -1
  87. package/lib/table/src/props.min.js +1 -1
  88. package/lib/table/src/table.js +288 -120
  89. package/lib/table/src/table.min.js +1 -1
  90. package/lib/table/style/style.css +15 -12
  91. package/lib/table/style/style.min.css +1 -1
  92. package/lib/toolbar/style/style.css +1 -1
  93. package/lib/toolbar/style/style.min.css +1 -1
  94. package/lib/v-x-e-table/src/conf.js +2 -1
  95. package/lib/v-x-e-table/src/conf.min.js +1 -1
  96. package/lib/v-x-e-table/src/renderer.js +4 -4
  97. package/lib/v-x-e-table/src/renderer.min.js +1 -1
  98. package/lib/validator/src/hook.js +12 -5
  99. package/lib/validator/src/hook.min.js +1 -1
  100. package/package.json +4 -4
  101. package/packages/edit/src/hook.ts +2 -2
  102. package/packages/export/src/hook.ts +24 -0
  103. package/packages/export/src/util.ts +17 -5
  104. package/packages/filter/src/hook.ts +2 -2
  105. package/packages/footer/src/footer.ts +4 -4
  106. package/packages/form/src/form.ts +10 -6
  107. package/packages/form/src/render.ts +4 -4
  108. package/packages/grid/src/grid.ts +48 -1
  109. package/packages/header/src/header.ts +7 -5
  110. package/packages/select/src/select.ts +5 -5
  111. package/packages/table/src/body.ts +18 -14
  112. package/packages/table/src/emits.ts +1 -0
  113. package/packages/table/src/props.ts +4 -1
  114. package/packages/table/src/table.ts +222 -88
  115. package/packages/v-x-e-table/src/conf.ts +2 -1
  116. package/packages/v-x-e-table/src/renderer.ts +4 -4
  117. package/packages/validator/src/hook.ts +9 -5
  118. package/styles/header.scss +9 -12
  119. package/styles/table.scss +9 -3
  120. package/styles/variable.scss +2 -2
  121. package/types/column.d.ts +5 -1
  122. package/types/form-item.d.ts +5 -1
  123. package/types/form.d.ts +5 -1
  124. package/types/grid.d.ts +4 -0
  125. package/types/modal.d.ts +4 -5
  126. package/types/table.d.ts +53 -11
  127. package/types/validator.d.ts +5 -1
@@ -261,6 +261,7 @@ export default defineComponent({
261
261
  treeExpandedReserveRowMap: {},
262
262
  // 完整数据、条件处理后
263
263
  tableFullData: [],
264
+ treeFullData: [],
264
265
  afterFullData: [],
265
266
  tableSynchData: [],
266
267
  tableSourceData: [],
@@ -332,7 +333,11 @@ export default defineComponent({
332
333
  })
333
334
 
334
335
  const computeColumnOpts = computed(() => {
335
- return Object.assign({}, props.columnConfig) as VxeTablePropTypes.ColumnOpts
336
+ return Object.assign({}, GlobalConfig.table.columnConfig, props.columnConfig) as VxeTablePropTypes.ColumnOpts
337
+ })
338
+
339
+ const computeRowOpts = computed(() => {
340
+ return Object.assign({}, GlobalConfig.table.rowConfig, props.rowConfig) as VxeTablePropTypes.RowOpts
336
341
  })
337
342
 
338
343
  const computeResizableOpts = computed(() => {
@@ -539,6 +544,8 @@ export default defineComponent({
539
544
  computeValidOpts,
540
545
  computeSXOpts,
541
546
  computeSYOpts,
547
+ computeColumnOpts,
548
+ computeRowOpts,
542
549
  computeResizableOpts,
543
550
  computeSeqOpts,
544
551
  computeRadioOpts,
@@ -1131,7 +1138,7 @@ export default defineComponent({
1131
1138
  if (rest) {
1132
1139
  rest._index = _index
1133
1140
  } else {
1134
- fullDataRowIdData[rowid] = { row, rowid, index: -1, $index: -1, _index, items: [], parent: null }
1141
+ fullDataRowIdData[rowid] = { row, rowid, index: -1, $index: -1, _index, items: [], parent: null, level: 0 }
1135
1142
  }
1136
1143
  })
1137
1144
  }
@@ -1331,7 +1338,7 @@ export default defineComponent({
1331
1338
 
1332
1339
  // 如果是使用优化模式
1333
1340
  if (fixedType) {
1334
- if (scrollXLoad || scrollYLoad || (allColumnOverflow ? isAllOverflow : allColumnOverflow)) {
1341
+ if (scrollYLoad || (allColumnOverflow ? isAllOverflow : allColumnOverflow)) {
1335
1342
  if (!mergeList.length && !spanMethod && !(keyboardConfig && keyboardOpts.isMerge)) {
1336
1343
  tableColumn = fixedColumn
1337
1344
  } else {
@@ -1419,15 +1426,9 @@ export default defineComponent({
1419
1426
  const showTooltip = cellOverflow === true || cellOverflow === 'tooltip'
1420
1427
  let hasEllipsis = showTitle || showTooltip || showEllipsis
1421
1428
  const listElem = elemStore[`${name}-${layout}-list`]
1422
- // 滚动的渲染不支持动态行高
1423
- if (layout === 'header' || layout === 'footer') {
1424
- if (scrollXLoad && !hasEllipsis) {
1425
- hasEllipsis = true
1426
- }
1427
- } else {
1428
- if ((scrollXLoad || scrollYLoad) && !hasEllipsis) {
1429
- hasEllipsis = true
1430
- }
1429
+ // 纵向虚拟滚动不支持动态行高
1430
+ if (scrollYLoad && !hasEllipsis) {
1431
+ hasEllipsis = true
1431
1432
  }
1432
1433
  if (listElem) {
1433
1434
  XEUtils.arrayEach(listElem.querySelectorAll(`.${column.id}`), (elem: any) => {
@@ -1682,7 +1683,7 @@ export default defineComponent({
1682
1683
  childRecords = []
1683
1684
  }
1684
1685
  if (childRecords) {
1685
- tableMethods.loadChildren(row, childRecords).then(childRows => {
1686
+ tableMethods.loadTreeChildren(row, childRecords).then(childRows => {
1686
1687
  if (childRows.length && $xetable.findRowIndexOf(treeExpandeds, row) === -1) {
1687
1688
  treeExpandeds.push(row)
1688
1689
  }
@@ -1795,7 +1796,6 @@ export default defineComponent({
1795
1796
  nextTick(updateStyle)
1796
1797
  })
1797
1798
  }
1798
-
1799
1799
  /**
1800
1800
  * 加载表格数据
1801
1801
  * @param {Array} datas 数据
@@ -1804,27 +1804,56 @@ export default defineComponent({
1804
1804
  const { keepSource, treeConfig } = props
1805
1805
  const { editStore, scrollYLoad: oldScrollYLoad } = reactData
1806
1806
  const { scrollYStore, scrollXStore, lastScrollLeft, lastScrollTop } = internalData
1807
- const sYOpts = computeSYOpts.value
1808
- const tableFullData = datas ? datas.slice(0) : []
1809
- const scrollYLoad = !treeConfig && !!sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < tableFullData.length
1807
+ const treeOpts = computeTreeOpts.value
1808
+ const { transform } = treeOpts
1809
+ let treeData = []
1810
+ let fullData = datas ? datas.slice(0) : []
1811
+ if (treeConfig) {
1812
+ if (transform) {
1813
+ // 树结构自动转换
1814
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
1815
+ if (!treeOpts.rowtKey) {
1816
+ errLog('vxe.error.reqProp', ['tree-config.rowtKey'])
1817
+ }
1818
+ if (!treeOpts.parentKey) {
1819
+ errLog('vxe.error.reqProp', ['tree-config.parentKey'])
1820
+ }
1821
+ if (!treeOpts.children) {
1822
+ errLog('vxe.error.reqProp', ['tree-config.children'])
1823
+ }
1824
+ fullData.forEach(row => {
1825
+ if (row[treeOpts.children] && row[treeOpts.children].length) {
1826
+ warnLog('vxe.error.errConflicts', ['tree-config.transform', `row.${treeOpts.children}`])
1827
+ }
1828
+ })
1829
+ }
1830
+ treeData = XEUtils.toArrayTree(fullData, { key: treeOpts.rowtKey, parentKey: treeOpts.parentKey, children: treeOpts.children })
1831
+ fullData = treeData.slice(0)
1832
+ } else {
1833
+ treeData = fullData.slice(0)
1834
+ }
1835
+ }
1810
1836
  scrollYStore.startIndex = 0
1811
1837
  scrollYStore.endIndex = 1
1812
1838
  scrollXStore.startIndex = 0
1813
1839
  scrollXStore.endIndex = 1
1814
1840
  editStore.insertList = []
1815
1841
  editStore.removeList = []
1842
+ const sYLoad = updateScrollYStatus(fullData)
1843
+ reactData.scrollYLoad = sYLoad
1816
1844
  // 全量数据
1817
- internalData.tableFullData = tableFullData
1845
+ internalData.tableFullData = fullData
1846
+ internalData.treeFullData = treeData
1818
1847
  // 缓存数据
1819
- tablePrivateMethods.updateCache(true)
1848
+ tablePrivateMethods.cacheRowMap(true)
1820
1849
  // 原始数据
1821
1850
  internalData.tableSynchData = datas
1851
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
1822
1852
  if (keepSource) {
1823
- internalData.tableSourceData = XEUtils.clone(tableFullData, true)
1853
+ internalData.tableSourceData = XEUtils.clone(fullData, true)
1824
1854
  }
1825
- reactData.scrollYLoad = scrollYLoad
1826
1855
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
1827
- if (scrollYLoad) {
1856
+ if (sYLoad) {
1828
1857
  if (!(props.height || props.maxHeight)) {
1829
1858
  errLog('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}'])
1830
1859
  }
@@ -1850,8 +1879,8 @@ export default defineComponent({
1850
1879
  }).then(() => {
1851
1880
  computeScrollLoad()
1852
1881
  }).then(() => {
1853
- // 是否加载了数据
1854
- if (scrollYLoad) {
1882
+ // 是否启用了虚拟滚动
1883
+ if (sYLoad) {
1855
1884
  scrollYStore.endIndex = scrollYStore.visibleSize
1856
1885
  }
1857
1886
  handleReserveStatus()
@@ -1861,7 +1890,7 @@ export default defineComponent({
1861
1890
  .then(() => tableMethods.recalculate())
1862
1891
  .then(() => {
1863
1892
  // 是否变更虚拟滚动
1864
- if (oldScrollYLoad === scrollYLoad) {
1893
+ if (oldScrollYLoad === sYLoad) {
1865
1894
  restoreScrollLocation($xetable, lastScrollLeft, lastScrollTop).then(resolve)
1866
1895
  } else {
1867
1896
  setTimeout(() => restoreScrollLocation($xetable, lastScrollLeft, lastScrollTop).then(resolve))
@@ -2077,6 +2106,97 @@ export default defineComponent({
2077
2106
  })
2078
2107
  }
2079
2108
 
2109
+ const updateScrollYStatus = (fullData: any[]) => {
2110
+ const { treeConfig } = props
2111
+ const sYOpts = computeSYOpts.value
2112
+ const treeOpts = computeTreeOpts.value
2113
+ const { transform } = treeOpts
2114
+ const scrollYLoad = (transform || !treeConfig) && !!sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < fullData.length
2115
+ reactData.scrollYLoad = scrollYLoad
2116
+ return scrollYLoad
2117
+ }
2118
+
2119
+ const updateVirtualTreeData = () => {
2120
+ const { scrollYLoad: oldScrollYLoad, treeExpandeds } = reactData
2121
+ const { treeFullData } = internalData
2122
+ const treeOpts = computeTreeOpts.value
2123
+ const fullData: any[] = []
2124
+ XEUtils.eachTree(treeFullData, (row, index, items, path, parent) => {
2125
+ if (!parent || $xetable.findRowIndexOf(treeExpandeds, parent) > -1) {
2126
+ fullData.push(row)
2127
+ }
2128
+ }, treeOpts)
2129
+ const scrollYLoad = updateScrollYStatus(fullData)
2130
+ internalData.tableFullData = scrollYLoad ? fullData : treeFullData
2131
+ if (scrollYLoad || oldScrollYLoad !== scrollYLoad) {
2132
+ return tablePrivateMethods.handleTableData(true).then(() => tableMethods.recalculate())
2133
+ }
2134
+ return nextTick()
2135
+ }
2136
+
2137
+ /**
2138
+ * 展开与收起树节点
2139
+ * @param rows
2140
+ * @param expanded
2141
+ * @returns
2142
+ */
2143
+ const handleBaseTreeExpand = (rows: any[], expanded: boolean) => {
2144
+ const { treeExpandeds, treeLazyLoadeds, treeNodeColumn } = reactData
2145
+ const { fullAllDataRowIdData, tableFullData } = internalData
2146
+ const treeOpts = computeTreeOpts.value
2147
+ const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
2148
+ const result: any[] = []
2149
+ const columnIndex = tableMethods.getColumnIndex(treeNodeColumn)
2150
+ const $columnIndex = tableMethods.getVMColumnIndex(treeNodeColumn)
2151
+ let validRows = toggleMethod ? rows.filter((row: any) => toggleMethod({ $table: $xetable, expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
2152
+ if (accordion) {
2153
+ validRows = validRows.length ? [validRows[validRows.length - 1]] : []
2154
+ // 同一级只能展开一个
2155
+ const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
2156
+ if (matchObj) {
2157
+ XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
2158
+ }
2159
+ }
2160
+ if (expanded) {
2161
+ validRows.forEach((row: any) => {
2162
+ if ($xetable.findRowIndexOf(treeExpandeds, row) === -1) {
2163
+ const rest = fullAllDataRowIdData[getRowid($xetable, row)]
2164
+ const isLoad = lazy && row[hasChild] && !rest.treeLoaded && $xetable.findRowIndexOf(treeLazyLoadeds, row) === -1
2165
+ // 是否使用懒加载
2166
+ if (isLoad) {
2167
+ result.push(handleAsyncTreeExpandChilds(row))
2168
+ } else {
2169
+ if (row[children] && row[children].length) {
2170
+ treeExpandeds.push(row)
2171
+ }
2172
+ }
2173
+ }
2174
+ })
2175
+ } else {
2176
+ XEUtils.remove(treeExpandeds, row => $xetable.findRowIndexOf(validRows, row) > -1)
2177
+ }
2178
+ if (reserve) {
2179
+ validRows.forEach((row: any) => handleTreeExpandReserve(row, expanded))
2180
+ }
2181
+ return Promise.all(result).then(() => {
2182
+ return tableMethods.recalculate()
2183
+ })
2184
+ }
2185
+
2186
+ /**
2187
+ * 虚拟树的展开与收起
2188
+ * @param rows
2189
+ * @param expanded
2190
+ * @returns
2191
+ */
2192
+ const handleVirtualTreeExpand = (rows: any[], expanded: boolean) => {
2193
+ return handleBaseTreeExpand(rows, expanded).then(() => {
2194
+ return updateVirtualTreeData()
2195
+ }).then(() => {
2196
+ return tableMethods.recalculate()
2197
+ })
2198
+ }
2199
+
2080
2200
  /**
2081
2201
  * 纵向 Y 可视渲染处理
2082
2202
  */
@@ -2197,7 +2317,7 @@ export default defineComponent({
2197
2317
  tableSourceData[rowIndex] = record
2198
2318
  XEUtils.clear(row, undefined)
2199
2319
  Object.assign(row, tablePrivateMethods.defineField(Object.assign({}, record)))
2200
- tablePrivateMethods.updateCache(true)
2320
+ tablePrivateMethods.cacheRowMap(true)
2201
2321
  } else {
2202
2322
  XEUtils.destructuring(oRow, XEUtils.clone(row, true))
2203
2323
  }
@@ -2214,13 +2334,14 @@ export default defineComponent({
2214
2334
  /**
2215
2335
  * 用于树结构,给行数据加载子节点
2216
2336
  */
2217
- loadChildren (row, childRecords) {
2337
+ loadTreeChildren (row, childRecords) {
2338
+ const { keepSource } = props
2339
+ const { tableSourceData, fullDataRowIdData, fullAllDataRowIdData } = internalData
2340
+ const treeOpts = computeTreeOpts.value
2341
+ const { children } = treeOpts
2342
+ const rest = fullAllDataRowIdData[getRowid($xetable, row)]
2343
+ const parentLevel = rest ? rest.level : 0
2218
2344
  return tableMethods.createData(childRecords).then((rows) => {
2219
- const { keepSource } = props
2220
- const { fullDataRowIdData, fullAllDataRowIdData } = internalData
2221
- const { tableSourceData } = internalData
2222
- const treeOpts = computeTreeOpts.value
2223
- const { children } = treeOpts
2224
2345
  if (keepSource) {
2225
2346
  const rowid = getRowid($xetable, row)
2226
2347
  const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid($xetable, item), treeOpts)
@@ -2228,9 +2349,9 @@ export default defineComponent({
2228
2349
  matchObj.item[children] = XEUtils.clone(rows, true)
2229
2350
  }
2230
2351
  }
2231
- XEUtils.eachTree(rows, (childRow, index, items, path, parent) => {
2352
+ XEUtils.eachTree(rows, (childRow, index, items, path, parent, nodes) => {
2232
2353
  const rowid = getRowid($xetable, childRow)
2233
- const rest = { row: childRow, rowid, index: -1, _index: -1, $index: -1, items, parent }
2354
+ const rest = { row: childRow, rowid, index: -1, _index: -1, $index: -1, items, parent, level: parentLevel + nodes.length }
2234
2355
  fullDataRowIdData[rowid] = rest
2235
2356
  fullAllDataRowIdData[rowid] = rest
2236
2357
  }, treeOpts)
@@ -3220,12 +3341,16 @@ export default defineComponent({
3220
3341
  */
3221
3342
  closeFilter () {
3222
3343
  const { filterStore } = reactData
3344
+ const { column, visible } = filterStore
3223
3345
  Object.assign(filterStore, {
3224
3346
  isAllSelected: false,
3225
3347
  isIndeterminate: false,
3226
3348
  options: [],
3227
3349
  visible: false
3228
3350
  })
3351
+ if (visible) {
3352
+ $xetable.dispatchEvent('filter-visible', { column, property: column.property, filterList: $xetable.getCheckedFilters(), visible: false }, null)
3353
+ }
3229
3354
  return nextTick()
3230
3355
  },
3231
3356
  /**
@@ -3261,10 +3386,10 @@ export default defineComponent({
3261
3386
  return nextTick()
3262
3387
  },
3263
3388
  /**
3264
- * 重新加载展开行的内容
3389
+ * 重新懒加载展开行,并展开内容
3265
3390
  * @param {Row} row 行对象
3266
3391
  */
3267
- reloadExpandContent (row) {
3392
+ lazyExpandContent (row) {
3268
3393
  const { expandLazyLoadeds } = reactData
3269
3394
  const expandOpts = computeExpandOpts.value
3270
3395
  const { lazy } = expandOpts
@@ -3274,6 +3399,16 @@ export default defineComponent({
3274
3399
  }
3275
3400
  return nextTick()
3276
3401
  },
3402
+ /**
3403
+ * @deprecated 已废弃,请使用 lazyExpandContent
3404
+ */
3405
+ reloadExpandContent (row) {
3406
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3407
+ warnLog('vxe.error.delFunc', ['reloadExpandContent', 'lazyExpandContent'])
3408
+ }
3409
+ // 即将废弃
3410
+ return tableMethods.lazyExpandContent(row)
3411
+ },
3277
3412
  /**
3278
3413
  * 切换展开行
3279
3414
  */
@@ -3394,19 +3529,33 @@ export default defineComponent({
3394
3529
  return nextTick()
3395
3530
  },
3396
3531
  /**
3397
- * 重新加载树的子节点
3532
+ * 重新懒加载树节点,并展开该节点
3398
3533
  * @param {Row} row 行对象
3399
3534
  */
3400
- reloadTreeChilds (row) {
3535
+ lazyTreeChildren (row) {
3401
3536
  const { treeLazyLoadeds } = reactData
3402
3537
  const treeOpts = computeTreeOpts.value
3403
- const { lazy, hasChild } = treeOpts
3538
+ const { transform, lazy, hasChild } = treeOpts
3404
3539
  if (lazy && row[hasChild] && $xetable.findRowIndexOf(treeLazyLoadeds, row) === -1) {
3405
- tableMethods.clearTreeExpandLoaded(row)
3406
- .then(() => handleAsyncTreeExpandChilds(row))
3540
+ tableMethods.clearTreeExpandLoaded(row).then(() => {
3541
+ return handleAsyncTreeExpandChilds(row)
3542
+ }).then(() => {
3543
+ if (transform) {
3544
+ return updateVirtualTreeData()
3545
+ }
3546
+ }).then(() => {
3547
+ return tableMethods.recalculate()
3548
+ })
3407
3549
  }
3408
3550
  return nextTick()
3409
3551
  },
3552
+ reloadTreeChilds (row) {
3553
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3554
+ warnLog('vxe.error.delFunc', ['reloadTreeChilds', 'lazyTreeChildren'])
3555
+ }
3556
+ // 即将废弃
3557
+ return tableMethods.lazyTreeChildren(row)
3558
+ },
3410
3559
  /**
3411
3560
  * 切换/展开树节点
3412
3561
  */
@@ -3438,51 +3587,19 @@ export default defineComponent({
3438
3587
  * @param {Boolean} expanded 是否展开
3439
3588
  */
3440
3589
  setTreeExpand (rows, expanded) {
3441
- const { treeExpandeds, treeLazyLoadeds, treeNodeColumn } = reactData
3442
- const { fullAllDataRowIdData, tableFullData } = internalData
3443
3590
  const treeOpts = computeTreeOpts.value
3444
- const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3445
- const result: any[] = []
3446
- const columnIndex = tableMethods.getColumnIndex(treeNodeColumn)
3447
- const $columnIndex = tableMethods.getVMColumnIndex(treeNodeColumn)
3591
+ const { transform } = treeOpts
3448
3592
  if (rows) {
3449
3593
  if (!XEUtils.isArray(rows)) {
3450
3594
  rows = [rows]
3451
3595
  }
3452
3596
  if (rows.length) {
3453
- let validRows = toggleMethod ? rows.filter((row: any) => toggleMethod({ $table: $xetable, expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3454
- if (accordion) {
3455
- validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3456
- // 同一级只能展开一个
3457
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3458
- if (matchObj) {
3459
- XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3460
- }
3461
- }
3462
- if (expanded) {
3463
- validRows.forEach((row: any) => {
3464
- if ($xetable.findRowIndexOf(treeExpandeds, row) === -1) {
3465
- const rest = fullAllDataRowIdData[getRowid($xetable, row)]
3466
- const isLoad = lazy && row[hasChild] && !rest.treeLoaded && $xetable.findRowIndexOf(treeLazyLoadeds, row) === -1
3467
- // 是否使用懒加载
3468
- if (isLoad) {
3469
- result.push(handleAsyncTreeExpandChilds(row))
3470
- } else {
3471
- if (row[children] && row[children].length) {
3472
- treeExpandeds.push(row)
3473
- }
3474
- }
3475
- }
3476
- })
3597
+ // 如果为虚拟树
3598
+ if (transform) {
3599
+ return handleVirtualTreeExpand(rows, expanded)
3477
3600
  } else {
3478
- XEUtils.remove(treeExpandeds, row => $xetable.findRowIndexOf(validRows, row) > -1)
3479
- }
3480
- if (reserve) {
3481
- validRows.forEach((row: any) => handleTreeExpandReserve(row, expanded))
3601
+ return handleBaseTreeExpand(rows, expanded)
3482
3602
  }
3483
- return Promise.all(result).then(() => {
3484
- return tableMethods.recalculate()
3485
- })
3486
3603
  }
3487
3604
  }
3488
3605
  return nextTick()
@@ -3500,15 +3617,15 @@ export default defineComponent({
3500
3617
  */
3501
3618
  clearTreeExpand () {
3502
3619
  const { treeExpandeds } = reactData
3503
- const { tableFullData } = internalData
3620
+ const { treeFullData } = internalData
3504
3621
  const treeOpts = computeTreeOpts.value
3505
3622
  const { reserve } = treeOpts
3506
3623
  const isExists = treeExpandeds.length
3507
3624
  reactData.treeExpandeds = []
3508
3625
  if (reserve) {
3509
- XEUtils.eachTree(tableFullData, row => handleTreeExpandReserve(row, false), treeOpts)
3626
+ XEUtils.eachTree(treeFullData, row => handleTreeExpandReserve(row, false), treeOpts)
3510
3627
  }
3511
- return nextTick().then(() => {
3628
+ return updateVirtualTreeData().then(() => {
3512
3629
  if (isExists) {
3513
3630
  tableMethods.recalculate()
3514
3631
  }
@@ -4335,13 +4452,13 @@ export default defineComponent({
4335
4452
  * 更新数据行的 Map
4336
4453
  * 牺牲数据组装的耗时,用来换取使用过程中的流畅
4337
4454
  */
4338
- updateCache (isSource) {
4455
+ cacheRowMap (isSource) {
4339
4456
  const { treeConfig } = props
4340
4457
  const treeOpts = computeTreeOpts.value
4341
- let { fullDataRowIdData, fullAllDataRowIdData, tableFullData } = internalData
4458
+ let { fullDataRowIdData, fullAllDataRowIdData, tableFullData, treeFullData } = internalData
4342
4459
  const rowkey = getRowkey($xetable)
4343
4460
  const isLazy = treeConfig && treeOpts.lazy
4344
- const handleCache = (row: any, index: any, items: any, path?: any, parent?: any) => {
4461
+ const handleCache = (row: any, index: any, items: any, path?: any, parent?: any, nodes?: any[]) => {
4345
4462
  let rowid = getRowid($xetable, row)
4346
4463
  if (eqEmptyValue(rowid)) {
4347
4464
  rowid = getRowUniqueId()
@@ -4350,7 +4467,7 @@ export default defineComponent({
4350
4467
  if (isLazy && row[treeOpts.hasChild] && XEUtils.isUndefined(row[treeOpts.children])) {
4351
4468
  row[treeOpts.children] = null
4352
4469
  }
4353
- const rest = { row, rowid, index: treeConfig && parent ? -1 : index, _index: -1, $index: -1, items, parent }
4470
+ const rest = { row, rowid, index: treeConfig && parent ? -1 : index, _index: -1, $index: -1, items, parent, level: nodes ? nodes.length - 1 : 0 }
4354
4471
  if (isSource) {
4355
4472
  fullDataRowIdData[rowid] = rest
4356
4473
  }
@@ -4361,7 +4478,7 @@ export default defineComponent({
4361
4478
  }
4362
4479
  fullAllDataRowIdData = internalData.fullAllDataRowIdData = {}
4363
4480
  if (treeConfig) {
4364
- XEUtils.eachTree(tableFullData, handleCache, treeOpts)
4481
+ XEUtils.eachTree(treeFullData, handleCache, treeOpts)
4365
4482
  } else {
4366
4483
  tableFullData.forEach(handleCache)
4367
4484
  }
@@ -4628,10 +4745,10 @@ export default defineComponent({
4628
4745
  triggerHeaderHelpEvent (evnt, params) {
4629
4746
  const { column } = params
4630
4747
  const { titleHelp } = column
4631
- if (titleHelp.message) {
4748
+ if (titleHelp.content || titleHelp.message) {
4632
4749
  const { tooltipStore } = internalData
4633
4750
  const $tooltip = refTooltip.value
4634
- const content = getFuncText(titleHelp.message)
4751
+ const content = getFuncText(titleHelp.content || titleHelp.message)
4635
4752
  handleTargetEnterEvent()
4636
4753
  tooltipStore.visible = true
4637
4754
  if ($tooltip) {
@@ -5210,6 +5327,19 @@ export default defineComponent({
5210
5327
  }
5211
5328
  }
5212
5329
 
5330
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
5331
+ 'openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',').forEach(name => {
5332
+ ($xetable as any)[name] = function () {
5333
+ errLog('vxe.error.reqModule', ['Export'])
5334
+ }
5335
+ })
5336
+ 'clearValidate,fullValidate,validate'.split(',').forEach(name => {
5337
+ ($xetable as any)[name] = function () {
5338
+ errLog('vxe.error.reqModule', ['Validator'])
5339
+ }
5340
+ })
5341
+ }
5342
+
5213
5343
  Object.assign($xetable, tableMethods, tablePrivateMethods)
5214
5344
 
5215
5345
  /**
@@ -5417,12 +5547,16 @@ export default defineComponent({
5417
5547
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
5418
5548
  const customOpts = computeCustomOpts.value
5419
5549
  const mouseOpts = computeMouseOpts.value
5550
+ const rowOpts = computeRowOpts.value
5420
5551
  if (!props.id && props.customConfig && (customOpts.storage === true || (customOpts.storage && customOpts.storage.resizable) || (customOpts.storage && customOpts.storage.visible))) {
5421
5552
  errLog('vxe.error.reqProp', ['id'])
5422
5553
  }
5423
5554
  if (props.treeConfig && checkboxOpts.range) {
5424
5555
  errLog('vxe.error.noTree', ['checkbox-config.range'])
5425
5556
  }
5557
+ if (rowOpts.height && !props.showOverflow) {
5558
+ warnLog('vxe.error.notProp', ['table.show-overflow'])
5559
+ }
5426
5560
  if (!$xetable.handleUpdateCellAreas) {
5427
5561
  if (props.clipConfig) {
5428
5562
  warnLog('vxe.error.notProp', ['clip-config'])
@@ -20,7 +20,6 @@ const GlobalConfig: VXETableGlobalConfig = {
20
20
  // resizeInterval: 500,
21
21
  // size: null,
22
22
  // zIndex: null,
23
- // resizable: false,
24
23
  // autoResize: false,
25
24
  // stripe: false,
26
25
  // border: false,
@@ -66,6 +65,8 @@ const GlobalConfig: VXETableGlobalConfig = {
66
65
  showIcon: true
67
66
  },
68
67
  treeConfig: {
68
+ rowtKey: 'id',
69
+ parentKey: 'parentId',
69
70
  children: 'children',
70
71
  hasChild: 'hasChild',
71
72
  indent: 20,
@@ -549,7 +549,7 @@ const renderMap: { [name: string]: any } = {
549
549
  renderEdit: nativeEditRender,
550
550
  renderDefault: nativeEditRender,
551
551
  renderFilter: nativeFilterRender,
552
- filterMethod: handleFilterMethod,
552
+ defaultFilterMethod: handleFilterMethod,
553
553
  renderItemContent: nativeItemRender
554
554
  },
555
555
  textarea: {
@@ -575,7 +575,7 @@ const renderMap: { [name: string]: any } = {
575
575
  renderOpts.optionGroups ? renderNativeOptgroups(renderOpts, params, renderNativeOptions) : renderNativeOptions(renderOpts.options, renderOpts, params))
576
576
  })
577
577
  },
578
- filterMethod: handleFilterMethod,
578
+ defaultFilterMethod: handleFilterMethod,
579
579
  renderItemContent (renderOpts: any, params: any) {
580
580
  return [
581
581
  h('select', {
@@ -613,7 +613,7 @@ const renderMap: { [name: string]: any } = {
613
613
  },
614
614
  renderDefault: defaultEditRender,
615
615
  renderFilter: defaultFilterRender,
616
- filterMethod: handleFilterMethod,
616
+ defaultFilterMethod: handleFilterMethod,
617
617
  renderItemContent: defaultItemRender
618
618
  },
619
619
  $textarea: {
@@ -647,7 +647,7 @@ const renderMap: { [name: string]: any } = {
647
647
  })
648
648
  })
649
649
  },
650
- filterMethod: handleFilterMethod,
650
+ defaultFilterMethod: handleFilterMethod,
651
651
  renderItemContent (renderOpts: any, params: any) {
652
652
  const { data, property } = params
653
653
  const { options, optionProps, optionGroups, optionGroupProps } = renderOpts
@@ -27,8 +27,12 @@ class Rule {
27
27
  * 获取校验不通过的消息
28
28
  * 支持国际化翻译
29
29
  */
30
+ get content () {
31
+ return getFuncText(this.$options.content || this.$options.message)
32
+ }
33
+
30
34
  get message () {
31
- return getFuncText(this.$options.message)
35
+ return this.content
32
36
  }
33
37
 
34
38
  [key: string]: any
@@ -272,7 +276,7 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
272
276
  const rules = XEUtils.get(editRules, property)
273
277
  if (rules) {
274
278
  const cellValue = XEUtils.isUndefined(val) ? XEUtils.get(row, property) : val
275
- rules.forEach((rule: any) => {
279
+ rules.forEach((rule) => {
276
280
  const { type, trigger, required } = rule
277
281
  if (validType === 'all' || !trigger || validType === trigger) {
278
282
  if (XEUtils.isFunction(rule.validator)) {
@@ -289,13 +293,13 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
289
293
  if (customValid) {
290
294
  if (XEUtils.isError(customValid)) {
291
295
  validRuleErr = true
292
- errorRules.push(new Rule({ type: 'custom', trigger, message: customValid.message, rule: new Rule(rule) }))
296
+ errorRules.push(new Rule({ type: 'custom', trigger, content: customValid.message, rule: new Rule(rule) }))
293
297
  } else if (customValid.catch) {
294
298
  // 如果为异步校验(注:异步校验是并发无序的)
295
299
  syncVailds.push(
296
300
  customValid.catch((e: any) => {
297
301
  validRuleErr = true
298
- errorRules.push(new Rule({ type: 'custom', trigger, message: e && e.message ? e.message : rule.message, rule: new Rule(rule) }))
302
+ errorRules.push(new Rule({ type: 'custom', trigger, content: e && e.message ? e.message : (rule.content || rule.message), rule: new Rule(rule) }))
299
303
  })
300
304
  )
301
305
  }
@@ -367,7 +371,7 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
367
371
  const validOpts = computeValidOpts.value
368
372
  const { rule, row, column, cell } = params
369
373
  const validTip = refValidTooltip.value
370
- const content = rule.message
374
+ const content = rule.content
371
375
  return nextTick().then(() => {
372
376
  Object.assign(validStore, {
373
377
  row,