vxe-table 4.1.0 → 4.1.3

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 (72) hide show
  1. package/README.md +1 -0
  2. package/README.zh-TW.md +1 -0
  3. package/es/edit/src/hook.js +2 -2
  4. package/es/export/src/hook.js +24 -0
  5. package/es/export/src/util.js +20 -8
  6. package/es/footer/src/footer.js +4 -4
  7. package/es/form/src/form.js +13 -6
  8. package/es/form/src/render.js +4 -4
  9. package/es/grid/src/grid.js +48 -1
  10. package/es/header/src/header.js +7 -5
  11. package/es/select/src/select.js +5 -5
  12. package/es/table/src/body.js +18 -14
  13. package/es/table/src/cell.js +70 -54
  14. package/es/table/src/props.js +4 -1
  15. package/es/table/src/table.js +208 -97
  16. package/es/v-x-e-table/src/conf.js +2 -3
  17. package/es/validator/src/hook.js +12 -5
  18. package/helper/vetur/attributes.json +16 -8
  19. package/helper/vetur/tags.json +2 -0
  20. package/lib/edit/src/hook.js +2 -2
  21. package/lib/edit/src/hook.min.js +1 -1
  22. package/lib/export/src/hook.js +28 -0
  23. package/lib/export/src/hook.min.js +1 -1
  24. package/lib/export/src/util.js +21 -7
  25. package/lib/export/src/util.min.js +1 -1
  26. package/lib/footer/src/footer.js +4 -4
  27. package/lib/footer/src/footer.min.js +1 -1
  28. package/lib/form/src/form.js +23 -6
  29. package/lib/form/src/form.min.js +1 -1
  30. package/lib/form/src/render.js +4 -4
  31. package/lib/form/src/render.min.js +1 -1
  32. package/lib/grid/src/grid.js +56 -1
  33. package/lib/grid/src/grid.min.js +1 -1
  34. package/lib/header/src/header.js +7 -5
  35. package/lib/header/src/header.min.js +1 -1
  36. package/lib/index.umd.js +536 -220
  37. package/lib/index.umd.min.js +1 -1
  38. package/lib/select/src/select.js +5 -5
  39. package/lib/table/src/body.js +18 -14
  40. package/lib/table/src/body.min.js +1 -1
  41. package/lib/table/src/cell.js +92 -35
  42. package/lib/table/src/cell.min.js +1 -1
  43. package/lib/table/src/props.js +4 -1
  44. package/lib/table/src/props.min.js +1 -1
  45. package/lib/table/src/table.js +265 -133
  46. package/lib/table/src/table.min.js +1 -1
  47. package/lib/v-x-e-table/src/conf.js +2 -3
  48. package/lib/v-x-e-table/src/conf.min.js +1 -1
  49. package/lib/validator/src/hook.js +12 -5
  50. package/lib/validator/src/hook.min.js +1 -1
  51. package/package.json +2 -2
  52. package/packages/edit/src/hook.ts +2 -2
  53. package/packages/export/src/hook.ts +24 -0
  54. package/packages/export/src/util.ts +17 -5
  55. package/packages/footer/src/footer.ts +4 -4
  56. package/packages/form/src/form.ts +10 -6
  57. package/packages/form/src/render.ts +4 -4
  58. package/packages/grid/src/grid.ts +48 -1
  59. package/packages/header/src/header.ts +7 -5
  60. package/packages/select/src/select.ts +5 -5
  61. package/packages/table/src/body.ts +18 -14
  62. package/packages/table/src/cell.ts +77 -44
  63. package/packages/table/src/props.ts +4 -1
  64. package/packages/table/src/table.ts +211 -96
  65. package/packages/v-x-e-table/src/conf.ts +2 -3
  66. package/packages/validator/src/hook.ts +9 -5
  67. package/types/column.d.ts +5 -1
  68. package/types/form-item.d.ts +5 -1
  69. package/types/form.d.ts +5 -1
  70. package/types/modal.d.ts +4 -5
  71. package/types/table.d.ts +49 -14
  72. 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,39 +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
1807
  const treeOpts = computeTreeOpts.value
1809
- if (treeConfig && treeOpts.transform) {
1810
- if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
1811
- if (!treeOpts.rowtKey) {
1812
- errLog('vxe.error.reqProp', ['table.tree-config.rowtKey'])
1813
- }
1814
- if (!treeOpts.parentKey) {
1815
- errLog('vxe.error.reqProp', ['table.tree-config.parentKey'])
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.rowField) {
1816
+ errLog('vxe.error.reqProp', ['tree-config.rowField'])
1817
+ }
1818
+ if (!treeOpts.parentField) {
1819
+ errLog('vxe.error.reqProp', ['tree-config.parentField'])
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
+ })
1816
1829
  }
1830
+ treeData = XEUtils.toArrayTree(fullData, { key: treeOpts.rowField, parentKey: treeOpts.parentField, children: treeOpts.children })
1831
+ fullData = treeData.slice(0)
1832
+ } else {
1833
+ treeData = fullData.slice(0)
1817
1834
  }
1818
- datas = XEUtils.toArrayTree(datas, { key: treeOpts.rowtKey, parentKey: treeOpts.parentKey, children: treeOpts.children })
1819
1835
  }
1820
- const tableFullData = datas ? datas.slice(0) : []
1821
- const scrollYLoad = !treeConfig && !!sYOpts.enabled && sYOpts.gt > -1 && sYOpts.gt < tableFullData.length
1822
1836
  scrollYStore.startIndex = 0
1823
1837
  scrollYStore.endIndex = 1
1824
1838
  scrollXStore.startIndex = 0
1825
1839
  scrollXStore.endIndex = 1
1826
1840
  editStore.insertList = []
1827
1841
  editStore.removeList = []
1842
+ const sYLoad = updateScrollYStatus(fullData)
1843
+ reactData.scrollYLoad = sYLoad
1828
1844
  // 全量数据
1829
- internalData.tableFullData = tableFullData
1845
+ internalData.tableFullData = fullData
1846
+ internalData.treeFullData = treeData
1830
1847
  // 缓存数据
1831
- tablePrivateMethods.updateCache(true)
1848
+ tablePrivateMethods.cacheRowMap(true)
1832
1849
  // 原始数据
1833
1850
  internalData.tableSynchData = datas
1851
+ // 克隆原数据,用于显示编辑状态,与编辑值做对比
1834
1852
  if (keepSource) {
1835
- internalData.tableSourceData = XEUtils.clone(tableFullData, true)
1853
+ internalData.tableSourceData = XEUtils.clone(fullData, true)
1836
1854
  }
1837
- reactData.scrollYLoad = scrollYLoad
1838
1855
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
1839
- if (scrollYLoad) {
1856
+ if (sYLoad) {
1840
1857
  if (!(props.height || props.maxHeight)) {
1841
1858
  errLog('vxe.error.reqProp', ['table.height | table.max-height | table.scroll-y={enabled: false}'])
1842
1859
  }
@@ -1862,8 +1879,8 @@ export default defineComponent({
1862
1879
  }).then(() => {
1863
1880
  computeScrollLoad()
1864
1881
  }).then(() => {
1865
- // 是否加载了数据
1866
- if (scrollYLoad) {
1882
+ // 是否启用了虚拟滚动
1883
+ if (sYLoad) {
1867
1884
  scrollYStore.endIndex = scrollYStore.visibleSize
1868
1885
  }
1869
1886
  handleReserveStatus()
@@ -1873,7 +1890,7 @@ export default defineComponent({
1873
1890
  .then(() => tableMethods.recalculate())
1874
1891
  .then(() => {
1875
1892
  // 是否变更虚拟滚动
1876
- if (oldScrollYLoad === scrollYLoad) {
1893
+ if (oldScrollYLoad === sYLoad) {
1877
1894
  restoreScrollLocation($xetable, lastScrollLeft, lastScrollTop).then(resolve)
1878
1895
  } else {
1879
1896
  setTimeout(() => restoreScrollLocation($xetable, lastScrollLeft, lastScrollTop).then(resolve))
@@ -2089,6 +2106,97 @@ export default defineComponent({
2089
2106
  })
2090
2107
  }
2091
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
+
2092
2200
  /**
2093
2201
  * 纵向 Y 可视渲染处理
2094
2202
  */
@@ -2209,7 +2317,7 @@ export default defineComponent({
2209
2317
  tableSourceData[rowIndex] = record
2210
2318
  XEUtils.clear(row, undefined)
2211
2319
  Object.assign(row, tablePrivateMethods.defineField(Object.assign({}, record)))
2212
- tablePrivateMethods.updateCache(true)
2320
+ tablePrivateMethods.cacheRowMap(true)
2213
2321
  } else {
2214
2322
  XEUtils.destructuring(oRow, XEUtils.clone(row, true))
2215
2323
  }
@@ -2226,13 +2334,14 @@ export default defineComponent({
2226
2334
  /**
2227
2335
  * 用于树结构,给行数据加载子节点
2228
2336
  */
2229
- 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
2230
2344
  return tableMethods.createData(childRecords).then((rows) => {
2231
- const { keepSource } = props
2232
- const { fullDataRowIdData, fullAllDataRowIdData } = internalData
2233
- const { tableSourceData } = internalData
2234
- const treeOpts = computeTreeOpts.value
2235
- const { children } = treeOpts
2236
2345
  if (keepSource) {
2237
2346
  const rowid = getRowid($xetable, row)
2238
2347
  const matchObj = XEUtils.findTree(tableSourceData, (item) => rowid === getRowid($xetable, item), treeOpts)
@@ -2240,9 +2349,9 @@ export default defineComponent({
2240
2349
  matchObj.item[children] = XEUtils.clone(rows, true)
2241
2350
  }
2242
2351
  }
2243
- XEUtils.eachTree(rows, (childRow, index, items, path, parent) => {
2352
+ XEUtils.eachTree(rows, (childRow, index, items, path, parent, nodes) => {
2244
2353
  const rowid = getRowid($xetable, childRow)
2245
- 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 }
2246
2355
  fullDataRowIdData[rowid] = rest
2247
2356
  fullAllDataRowIdData[rowid] = rest
2248
2357
  }, treeOpts)
@@ -3277,10 +3386,10 @@ export default defineComponent({
3277
3386
  return nextTick()
3278
3387
  },
3279
3388
  /**
3280
- * 重新加载展开行的内容
3389
+ * 重新懒加载展开行,并展开内容
3281
3390
  * @param {Row} row 行对象
3282
3391
  */
3283
- reloadExpandContent (row) {
3392
+ reloadRowExpand (row) {
3284
3393
  const { expandLazyLoadeds } = reactData
3285
3394
  const expandOpts = computeExpandOpts.value
3286
3395
  const { lazy } = expandOpts
@@ -3290,6 +3399,13 @@ export default defineComponent({
3290
3399
  }
3291
3400
  return nextTick()
3292
3401
  },
3402
+ reloadExpandContent (row) {
3403
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3404
+ warnLog('vxe.error.delFunc', ['reloadExpandContent', 'reloadRowExpand'])
3405
+ }
3406
+ // 即将废弃
3407
+ return tableMethods.reloadRowExpand(row)
3408
+ },
3293
3409
  /**
3294
3410
  * 切换展开行
3295
3411
  */
@@ -3410,19 +3526,33 @@ export default defineComponent({
3410
3526
  return nextTick()
3411
3527
  },
3412
3528
  /**
3413
- * 重新加载树的子节点
3529
+ * 重新懒加载树节点,并展开该节点
3414
3530
  * @param {Row} row 行对象
3415
3531
  */
3416
- reloadTreeChilds (row) {
3532
+ reloadTreeExpand (row) {
3417
3533
  const { treeLazyLoadeds } = reactData
3418
3534
  const treeOpts = computeTreeOpts.value
3419
- const { lazy, hasChild } = treeOpts
3535
+ const { transform, lazy, hasChild } = treeOpts
3420
3536
  if (lazy && row[hasChild] && $xetable.findRowIndexOf(treeLazyLoadeds, row) === -1) {
3421
- tableMethods.clearTreeExpandLoaded(row)
3422
- .then(() => handleAsyncTreeExpandChilds(row))
3537
+ tableMethods.clearTreeExpandLoaded(row).then(() => {
3538
+ return handleAsyncTreeExpandChilds(row)
3539
+ }).then(() => {
3540
+ if (transform) {
3541
+ return updateVirtualTreeData()
3542
+ }
3543
+ }).then(() => {
3544
+ return tableMethods.recalculate()
3545
+ })
3423
3546
  }
3424
3547
  return nextTick()
3425
3548
  },
3549
+ reloadTreeChilds (row) {
3550
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
3551
+ warnLog('vxe.error.delFunc', ['reloadTreeChilds', 'reloadTreeExpand'])
3552
+ }
3553
+ // 即将废弃
3554
+ return tableMethods.reloadTreeExpand(row)
3555
+ },
3426
3556
  /**
3427
3557
  * 切换/展开树节点
3428
3558
  */
@@ -3454,51 +3584,19 @@ export default defineComponent({
3454
3584
  * @param {Boolean} expanded 是否展开
3455
3585
  */
3456
3586
  setTreeExpand (rows, expanded) {
3457
- const { treeExpandeds, treeLazyLoadeds, treeNodeColumn } = reactData
3458
- const { fullAllDataRowIdData, tableFullData } = internalData
3459
3587
  const treeOpts = computeTreeOpts.value
3460
- const { reserve, lazy, hasChild, children, accordion, toggleMethod } = treeOpts
3461
- const result: any[] = []
3462
- const columnIndex = tableMethods.getColumnIndex(treeNodeColumn)
3463
- const $columnIndex = tableMethods.getVMColumnIndex(treeNodeColumn)
3588
+ const { transform } = treeOpts
3464
3589
  if (rows) {
3465
3590
  if (!XEUtils.isArray(rows)) {
3466
3591
  rows = [rows]
3467
3592
  }
3468
3593
  if (rows.length) {
3469
- let validRows = toggleMethod ? rows.filter((row: any) => toggleMethod({ $table: $xetable, expanded, column: treeNodeColumn, columnIndex, $columnIndex, row })) : rows
3470
- if (accordion) {
3471
- validRows = validRows.length ? [validRows[validRows.length - 1]] : []
3472
- // 同一级只能展开一个
3473
- const matchObj = XEUtils.findTree(tableFullData, item => item === validRows[0], treeOpts)
3474
- if (matchObj) {
3475
- XEUtils.remove(treeExpandeds, item => matchObj.items.indexOf(item) > -1)
3476
- }
3477
- }
3478
- if (expanded) {
3479
- validRows.forEach((row: any) => {
3480
- if ($xetable.findRowIndexOf(treeExpandeds, row) === -1) {
3481
- const rest = fullAllDataRowIdData[getRowid($xetable, row)]
3482
- const isLoad = lazy && row[hasChild] && !rest.treeLoaded && $xetable.findRowIndexOf(treeLazyLoadeds, row) === -1
3483
- // 是否使用懒加载
3484
- if (isLoad) {
3485
- result.push(handleAsyncTreeExpandChilds(row))
3486
- } else {
3487
- if (row[children] && row[children].length) {
3488
- treeExpandeds.push(row)
3489
- }
3490
- }
3491
- }
3492
- })
3594
+ // 如果为虚拟树
3595
+ if (transform) {
3596
+ return handleVirtualTreeExpand(rows, expanded)
3493
3597
  } else {
3494
- XEUtils.remove(treeExpandeds, row => $xetable.findRowIndexOf(validRows, row) > -1)
3598
+ return handleBaseTreeExpand(rows, expanded)
3495
3599
  }
3496
- if (reserve) {
3497
- validRows.forEach((row: any) => handleTreeExpandReserve(row, expanded))
3498
- }
3499
- return Promise.all(result).then(() => {
3500
- return tableMethods.recalculate()
3501
- })
3502
3600
  }
3503
3601
  }
3504
3602
  return nextTick()
@@ -3516,15 +3614,15 @@ export default defineComponent({
3516
3614
  */
3517
3615
  clearTreeExpand () {
3518
3616
  const { treeExpandeds } = reactData
3519
- const { tableFullData } = internalData
3617
+ const { treeFullData } = internalData
3520
3618
  const treeOpts = computeTreeOpts.value
3521
3619
  const { reserve } = treeOpts
3522
3620
  const isExists = treeExpandeds.length
3523
3621
  reactData.treeExpandeds = []
3524
3622
  if (reserve) {
3525
- XEUtils.eachTree(tableFullData, row => handleTreeExpandReserve(row, false), treeOpts)
3623
+ XEUtils.eachTree(treeFullData, row => handleTreeExpandReserve(row, false), treeOpts)
3526
3624
  }
3527
- return nextTick().then(() => {
3625
+ return updateVirtualTreeData().then(() => {
3528
3626
  if (isExists) {
3529
3627
  tableMethods.recalculate()
3530
3628
  }
@@ -4351,13 +4449,13 @@ export default defineComponent({
4351
4449
  * 更新数据行的 Map
4352
4450
  * 牺牲数据组装的耗时,用来换取使用过程中的流畅
4353
4451
  */
4354
- updateCache (isSource) {
4452
+ cacheRowMap (isSource) {
4355
4453
  const { treeConfig } = props
4356
4454
  const treeOpts = computeTreeOpts.value
4357
- let { fullDataRowIdData, fullAllDataRowIdData, tableFullData } = internalData
4455
+ let { fullDataRowIdData, fullAllDataRowIdData, tableFullData, treeFullData } = internalData
4358
4456
  const rowkey = getRowkey($xetable)
4359
4457
  const isLazy = treeConfig && treeOpts.lazy
4360
- const handleCache = (row: any, index: any, items: any, path?: any, parent?: any) => {
4458
+ const handleCache = (row: any, index: any, items: any, path?: any, parent?: any, nodes?: any[]) => {
4361
4459
  let rowid = getRowid($xetable, row)
4362
4460
  if (eqEmptyValue(rowid)) {
4363
4461
  rowid = getRowUniqueId()
@@ -4366,7 +4464,7 @@ export default defineComponent({
4366
4464
  if (isLazy && row[treeOpts.hasChild] && XEUtils.isUndefined(row[treeOpts.children])) {
4367
4465
  row[treeOpts.children] = null
4368
4466
  }
4369
- const rest = { row, rowid, index: treeConfig && parent ? -1 : index, _index: -1, $index: -1, items, parent }
4467
+ const rest = { row, rowid, index: treeConfig && parent ? -1 : index, _index: -1, $index: -1, items, parent, level: nodes ? nodes.length - 1 : 0 }
4370
4468
  if (isSource) {
4371
4469
  fullDataRowIdData[rowid] = rest
4372
4470
  }
@@ -4377,7 +4475,7 @@ export default defineComponent({
4377
4475
  }
4378
4476
  fullAllDataRowIdData = internalData.fullAllDataRowIdData = {}
4379
4477
  if (treeConfig) {
4380
- XEUtils.eachTree(tableFullData, handleCache, treeOpts)
4478
+ XEUtils.eachTree(treeFullData, handleCache, treeOpts)
4381
4479
  } else {
4382
4480
  tableFullData.forEach(handleCache)
4383
4481
  }
@@ -4644,10 +4742,10 @@ export default defineComponent({
4644
4742
  triggerHeaderHelpEvent (evnt, params) {
4645
4743
  const { column } = params
4646
4744
  const { titleHelp } = column
4647
- if (titleHelp.message) {
4745
+ if (titleHelp.content || titleHelp.message) {
4648
4746
  const { tooltipStore } = internalData
4649
4747
  const $tooltip = refTooltip.value
4650
- const content = getFuncText(titleHelp.message)
4748
+ const content = getFuncText(titleHelp.content || titleHelp.message)
4651
4749
  handleTargetEnterEvent()
4652
4750
  tooltipStore.visible = true
4653
4751
  if ($tooltip) {
@@ -5226,6 +5324,19 @@ export default defineComponent({
5226
5324
  }
5227
5325
  }
5228
5326
 
5327
+ if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
5328
+ 'openExport,openPrint,exportData,openImport,importData,saveFile,readFile,importByFile,print'.split(',').forEach(name => {
5329
+ ($xetable as any)[name] = function () {
5330
+ errLog('vxe.error.reqModule', ['Export'])
5331
+ }
5332
+ })
5333
+ 'clearValidate,fullValidate,validate'.split(',').forEach(name => {
5334
+ ($xetable as any)[name] = function () {
5335
+ errLog('vxe.error.reqModule', ['Validator'])
5336
+ }
5337
+ })
5338
+ }
5339
+
5229
5340
  Object.assign($xetable, tableMethods, tablePrivateMethods)
5230
5341
 
5231
5342
  /**
@@ -5433,12 +5544,16 @@ export default defineComponent({
5433
5544
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
5434
5545
  const customOpts = computeCustomOpts.value
5435
5546
  const mouseOpts = computeMouseOpts.value
5547
+ const rowOpts = computeRowOpts.value
5436
5548
  if (!props.id && props.customConfig && (customOpts.storage === true || (customOpts.storage && customOpts.storage.resizable) || (customOpts.storage && customOpts.storage.visible))) {
5437
5549
  errLog('vxe.error.reqProp', ['id'])
5438
5550
  }
5439
5551
  if (props.treeConfig && checkboxOpts.range) {
5440
5552
  errLog('vxe.error.noTree', ['checkbox-config.range'])
5441
5553
  }
5554
+ if (rowOpts.height && !props.showOverflow) {
5555
+ warnLog('vxe.error.notProp', ['table.show-overflow'])
5556
+ }
5442
5557
  if (!$xetable.handleUpdateCellAreas) {
5443
5558
  if (props.clipConfig) {
5444
5559
  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,8 +65,8 @@ const GlobalConfig: VXETableGlobalConfig = {
66
65
  showIcon: true
67
66
  },
68
67
  treeConfig: {
69
- rowtKey: 'id',
70
- parentKey: 'parentId',
68
+ rowField: 'id',
69
+ parentField: 'parentId',
71
70
  children: 'children',
72
71
  hasChild: 'hasChild',
73
72
  indent: 20,
@@ -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,
package/types/column.d.ts CHANGED
@@ -104,8 +104,12 @@ export namespace VxeColumnPropTypes {
104
104
  export type FooterExportMethod = (params: FooterExportParams) => string | number;
105
105
 
106
106
  export interface TitleHelp {
107
- message?: string | number;
107
+ content?: string | number;
108
108
  icon?: string;
109
+ /**
110
+ * @deprecated 已废弃,请使用 content
111
+ */
112
+ message?: string;
109
113
  }
110
114
 
111
115
  export type CellType = 'auto' | 'number' | 'string';
@@ -92,10 +92,14 @@ export namespace VxeFormItemPropTypes {
92
92
  export type ClassName = string | ((params: ClassNameParams) => string);
93
93
 
94
94
  interface PrefixOption {
95
- message?: string;
95
+ content?: string;
96
96
  enterable?: boolean;
97
97
  theme?: string;
98
98
  icon?: string;
99
+ /**
100
+ * @deprecated 已废弃,请使用 content
101
+ */
102
+ message?: string;
99
103
  }
100
104
  export type TitlePrefix = PrefixOption
101
105
  export type TitleSuffix = PrefixOption
package/types/form.d.ts CHANGED
@@ -235,9 +235,13 @@ export namespace VxeFormDefines {
235
235
  /**
236
236
  * 提示消息
237
237
  */
238
- message?: string;
238
+ content?: string;
239
239
  trigger?: 'change';
240
240
  maxWidth?: number;
241
+ /**
242
+ * @deprecated 已废弃,请使用 content
243
+ */
244
+ message?: string;
241
245
  }
242
246
 
243
247
  interface ValidateErrorParams {
package/types/modal.d.ts CHANGED
@@ -167,11 +167,6 @@ export type VxeModalProps = {
167
167
  position?: VxeModalPropTypes.Position;
168
168
  title?: VxeModalPropTypes.Title;
169
169
  duration?: VxeModalPropTypes.Duration;
170
- /**
171
- * 请使用 content
172
- * @deprecated
173
- */
174
- message?: VxeModalPropTypes.Content;
175
170
  content?: VxeModalPropTypes.Content;
176
171
  cancelButtonText?: VxeModalPropTypes.CancelButtonText;
177
172
  confirmButtonText?: VxeModalPropTypes.ConfirmButtonText;
@@ -203,6 +198,10 @@ export type VxeModalProps = {
203
198
  animat?: VxeModalPropTypes.Animat;
204
199
  beforeHideMethod?: VxeModalPropTypes.BeforeHideMethod;
205
200
  slots?: VxeModalPropTypes.Slots;
201
+ /**
202
+ * @deprecated 已废弃,请使用 content
203
+ */
204
+ message?: VxeModalPropTypes.Content;
206
205
  }
207
206
 
208
207
  export type ModalSlots = {