vxe-table 4.4.6 → 4.5.0-beta.2

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 (133) hide show
  1. package/es/edit/src/hook.js +2 -2
  2. package/es/export/src/hook.js +21 -12
  3. package/es/icon/style/{iconfont.1688790429861.ttf → iconfont.1689121467376.ttf} +0 -0
  4. package/es/icon/style/iconfont.1689121467376.woff +0 -0
  5. package/es/icon/style/iconfont.1689121467376.woff2 +0 -0
  6. package/es/icon/style.css +25 -1
  7. package/{lib/icon/style/iconfont.1688790429861.ttf → es/iconfont.1689121467376.ttf} +0 -0
  8. package/es/iconfont.1689121467376.woff +0 -0
  9. package/es/iconfont.1689121467376.woff2 +0 -0
  10. package/es/locale/lang/en-US.js +6 -2
  11. package/es/locale/lang/es-ES.js +9 -5
  12. package/es/locale/lang/ja-JP.js +5 -2
  13. package/es/locale/lang/zh-CN.js +6 -2
  14. package/es/locale/lang/zh-TC.js +6 -2
  15. package/es/style.css +1 -1
  16. package/es/style.min.css +1 -1
  17. package/es/table/src/body.js +7 -7
  18. package/es/table/src/columnInfo.js +7 -0
  19. package/es/table/src/table.js +121 -65
  20. package/es/table/src/util.js +16 -0
  21. package/es/table/style.css +6 -12
  22. package/es/toolbar/src/toolbar.js +86 -39
  23. package/es/toolbar/style.css +45 -14
  24. package/es/tools/log.js +1 -1
  25. package/es/v-x-e-table/index.js +1 -1
  26. package/es/v-x-e-table/src/conf.js +19 -11
  27. package/es/v-x-e-table/style.css +25 -1
  28. package/es/validator/src/hook.js +61 -31
  29. package/es/vxe-icon/style.css +25 -1
  30. package/es/vxe-table/style.css +6 -12
  31. package/es/vxe-toolbar/style.css +45 -14
  32. package/helper/vetur/attributes.json +57 -13
  33. package/helper/vetur/tags.json +12 -1
  34. package/lib/edit/src/hook.js +2 -2
  35. package/lib/edit/src/hook.min.js +1 -1
  36. package/lib/export/src/hook.js +23 -12
  37. package/lib/export/src/hook.min.js +1 -1
  38. package/lib/{iconfont.1688790429861.ttf → icon/style/iconfont.1689121467376.ttf} +0 -0
  39. package/lib/icon/style/iconfont.1689121467376.woff +0 -0
  40. package/lib/icon/style/iconfont.1689121467376.woff2 +0 -0
  41. package/lib/icon/style/style.css +25 -1
  42. package/lib/icon/style/style.min.css +25 -1
  43. package/{es/iconfont.1688790429861.ttf → lib/iconfont.1689121467376.ttf} +0 -0
  44. package/lib/iconfont.1689121467376.woff +0 -0
  45. package/lib/iconfont.1689121467376.woff2 +0 -0
  46. package/lib/index.umd.js +314 -147
  47. package/lib/index.umd.min.js +1 -1
  48. package/lib/locale/lang/en-US.js +6 -2
  49. package/lib/locale/lang/en-US.min.js +1 -1
  50. package/lib/locale/lang/en-US.umd.js +6 -2
  51. package/lib/locale/lang/es-ES.js +9 -5
  52. package/lib/locale/lang/es-ES.min.js +1 -1
  53. package/lib/locale/lang/es-ES.umd.js +9 -5
  54. package/lib/locale/lang/ja-JP.js +5 -2
  55. package/lib/locale/lang/ja-JP.min.js +1 -1
  56. package/lib/locale/lang/ja-JP.umd.js +5 -2
  57. package/lib/locale/lang/zh-CN.js +6 -2
  58. package/lib/locale/lang/zh-CN.min.js +1 -1
  59. package/lib/locale/lang/zh-CN.umd.js +6 -2
  60. package/lib/locale/lang/zh-HK.min.js +1 -1
  61. package/lib/locale/lang/zh-HK.umd.js +6 -2
  62. package/lib/locale/lang/zh-MO.min.js +1 -1
  63. package/lib/locale/lang/zh-MO.umd.js +6 -2
  64. package/lib/locale/lang/zh-TC.js +6 -2
  65. package/lib/locale/lang/zh-TC.min.js +1 -1
  66. package/lib/locale/lang/zh-TC.umd.js +6 -2
  67. package/lib/locale/lang/zh-TW.min.js +1 -1
  68. package/lib/locale/lang/zh-TW.umd.js +6 -2
  69. package/lib/style.css +1 -1
  70. package/lib/style.min.css +1 -1
  71. package/lib/table/src/body.js +8 -8
  72. package/lib/table/src/body.min.js +1 -1
  73. package/lib/table/src/columnInfo.js +7 -0
  74. package/lib/table/src/columnInfo.min.js +1 -1
  75. package/lib/table/src/table.js +122 -73
  76. package/lib/table/src/table.min.js +1 -1
  77. package/lib/table/src/util.js +17 -0
  78. package/lib/table/src/util.min.js +1 -1
  79. package/lib/table/style/style.css +6 -12
  80. package/lib/table/style/style.min.css +1 -1
  81. package/lib/toolbar/src/toolbar.js +54 -14
  82. package/lib/toolbar/src/toolbar.min.js +1 -1
  83. package/lib/toolbar/style/style.css +45 -14
  84. package/lib/toolbar/style/style.min.css +1 -1
  85. package/lib/tools/log.js +1 -1
  86. package/lib/tools/log.min.js +1 -1
  87. package/lib/v-x-e-table/index.js +1 -1
  88. package/lib/v-x-e-table/index.min.js +1 -1
  89. package/lib/v-x-e-table/src/conf.js +12 -3
  90. package/lib/v-x-e-table/src/conf.min.js +1 -1
  91. package/lib/v-x-e-table/style/style.css +25 -1
  92. package/lib/v-x-e-table/style/style.min.css +1 -1
  93. package/lib/validator/src/hook.js +62 -33
  94. package/lib/validator/src/hook.min.js +1 -1
  95. package/lib/vxe-icon/style/style.css +25 -1
  96. package/lib/vxe-icon/style/style.min.css +1 -1
  97. package/lib/vxe-table/style/style.css +6 -12
  98. package/lib/vxe-table/style/style.min.css +1 -1
  99. package/lib/vxe-toolbar/style/style.css +45 -14
  100. package/lib/vxe-toolbar/style/style.min.css +1 -1
  101. package/package.json +1 -1
  102. package/packages/edit/src/hook.ts +2 -2
  103. package/packages/export/src/hook.ts +21 -12
  104. package/packages/locale/lang/en-US.ts +6 -2
  105. package/packages/locale/lang/es-ES.ts +9 -5
  106. package/packages/locale/lang/ja-JP.ts +5 -2
  107. package/packages/locale/lang/zh-CN.ts +6 -2
  108. package/packages/locale/lang/zh-TC.ts +6 -2
  109. package/packages/table/src/body.ts +7 -7
  110. package/packages/table/src/columnInfo.ts +8 -1
  111. package/packages/table/src/table.ts +113 -53
  112. package/packages/table/src/util.ts +17 -0
  113. package/packages/toolbar/src/toolbar.ts +87 -40
  114. package/packages/v-x-e-table/src/conf.ts +11 -3
  115. package/packages/validator/src/hook.ts +71 -30
  116. package/styles/icon/iconfont.ttf +0 -0
  117. package/styles/icon/iconfont.woff +0 -0
  118. package/styles/icon/iconfont.woff2 +0 -0
  119. package/styles/icon.scss +25 -1
  120. package/styles/table.scss +7 -21
  121. package/styles/toolbar.scss +36 -9
  122. package/types/column.d.ts +1 -0
  123. package/types/table.d.ts +23 -6
  124. package/types/toolbar.d.ts +9 -1
  125. package/types/validator.d.ts +2 -3
  126. package/es/icon/style/iconfont.1688790429861.woff +0 -0
  127. package/es/icon/style/iconfont.1688790429861.woff2 +0 -0
  128. package/es/iconfont.1688790429861.woff +0 -0
  129. package/es/iconfont.1688790429861.woff2 +0 -0
  130. package/lib/icon/style/iconfont.1688790429861.woff +0 -0
  131. package/lib/icon/style/iconfont.1688790429861.woff2 +0 -0
  132. package/lib/iconfont.1688790429861.woff +0 -0
  133. package/lib/iconfont.1688790429861.woff2 +0 -0
@@ -124,7 +124,7 @@ export default defineComponent({
124
124
  */
125
125
  const renderColumn = (seq: number | string, rowid: string, fixedType: any, rowLevel: number, row: any, rowIndex: number, $rowIndex: number, _rowIndex: number, column: any, $columnIndex: number, columns: any, items: any[]) => {
126
126
  const { columnKey, showOverflow: allColumnOverflow, cellClassName: allCellClassName, cellStyle, align: allAlign, spanMethod, mouseConfig, editConfig, editRules, tooltipConfig } = tableProps
127
- const { tableData, overflowX, scrollYLoad, currentColumn, mergeList, editStore, validStore, isAllOverflow } = tableReactData
127
+ const { tableData, overflowX, scrollYLoad, currentColumn, mergeList, editStore, isAllOverflow, validErrorMaps } = tableReactData
128
128
  const { afterFullData } = tableInternalData
129
129
  const validOpts = computeValidOpts.value
130
130
  const checkboxOpts = computeCheckboxOpts.value
@@ -154,7 +154,7 @@ export default defineComponent({
154
154
  let isDirty
155
155
  const tdOns: any = {}
156
156
  const cellAlign = align || allAlign
157
- const hasValidError = validStore.row === row && validStore.column === column
157
+ const errorValidItem = validErrorMaps[`${rowid}:${column.id}`]
158
158
  const showValidTip = editRules && validOpts.showMessage
159
159
  const attrs: any = { colid: column.id }
160
160
  const params: VxeTableDefines.CellRenderBodyParams = { $table: $xetable, $grid: $xetable.xegrid, seq, rowid, row, rowIndex, $rowIndex, _rowIndex, column, columnIndex, $columnIndex, _columnIndex, fixed: fixedType, type: renderType, isHidden: fixedHiddenColumn, level: rowLevel, visibleData: afterFullData, data: tableData, items }
@@ -271,17 +271,17 @@ export default defineComponent({
271
271
  title: showTitle ? $xetable.getCellLabel(row, column) : null
272
272
  }, column.renderCell(params))
273
273
  )
274
- if (showValidTip && hasValidError) {
274
+ if (showValidTip && errorValidItem) {
275
275
  tdVNs.push(
276
276
  h('div', {
277
277
  class: 'vxe-cell--valid',
278
- style: validStore.rule && validStore.rule.maxWidth ? {
279
- width: `${validStore.rule.maxWidth}px`
278
+ style: errorValidItem.rule && errorValidItem.rule.maxWidth ? {
279
+ width: `${errorValidItem.rule.maxWidth}px`
280
280
  } : null
281
281
  }, [
282
282
  h('span', {
283
283
  class: 'vxe-cell--valid-msg'
284
- }, validStore.content)
284
+ }, errorValidItem.content)
285
285
  ])
286
286
  )
287
287
  }
@@ -301,7 +301,7 @@ export default defineComponent({
301
301
  'fixed--hidden': fixedHiddenColumn,
302
302
  'col--dirty': isDirty,
303
303
  'col--actived': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
304
- 'col--valid-error': hasValidError,
304
+ 'col--valid-error': !!errorValidItem,
305
305
  'col--current': currentColumn === column
306
306
  },
307
307
  getPropClass(compCellClassName, params),
@@ -10,7 +10,7 @@ import { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types/all'
10
10
  export class ColumnInfo {
11
11
  title?: string
12
12
  type?: string
13
- property?: string
13
+ field?: string
14
14
 
15
15
  /* eslint-disable @typescript-eslint/no-use-before-define */
16
16
  constructor ($xetable: VxeTableConstructor & VxeTablePrivateMethods, _vm: any, { renderHeader, renderCell, renderFooter, renderData }: any = {}) {
@@ -109,11 +109,18 @@ export class ColumnInfo {
109
109
  checked: false,
110
110
  halfChecked: false,
111
111
  disabled: false,
112
+ // 分组层级
112
113
  level: 1,
114
+ // 跨行
113
115
  rowSpan: 1,
116
+ // 跨列
114
117
  colSpan: 1,
118
+ // 数据排序-自定义排序
115
119
  order: null,
120
+ // 数据排序-用于多列的先后顺序
116
121
  sortTime: 0,
122
+ // 列排序
123
+ customOrder: 0,
117
124
  renderWidth: 0,
118
125
  renderHeight: 0,
119
126
  resizeWidth: 0,
@@ -15,7 +15,7 @@ import TableFooterComponent from '../../footer'
15
15
  import tableProps from './props'
16
16
  import tableEmits from './emits'
17
17
  import VxeLoading from '../../loading/index'
18
- import { getRowUniqueId, clearTableAllStatus, getRowkey, getRowid, rowToVisible, colToVisible, getCellValue, setCellValue, handleFieldOrColumn, toTreePathSeq, restoreScrollLocation, restoreScrollListener, XEBodyScrollElement } from './util'
18
+ import { getRowUniqueId, clearTableAllStatus, getRowkey, getRowid, rowToVisible, colToVisible, getCellValue, setCellValue, handleFieldOrColumn, toTreePathSeq, restoreScrollLocation, restoreScrollListener, XEBodyScrollElement, getRootColumn } from './util'
19
19
  import { getSlotVNs } from '../../tools/vn'
20
20
 
21
21
  import { VxeGridConstructor, VxeGridPrivateMethods, VxeTableConstructor, TableReactData, TableInternalData, VxeTablePropTypes, VxeToolbarConstructor, VxeTooltipInstance, TablePrivateMethods, VxeTablePrivateRef, VxeTablePrivateComputed, VxeTablePrivateMethods, VxeTableMethods, TableMethods, VxeMenuPanelInstance, VxeTableDefines, VxeTableProps, VxeColumnPropTypes, VxeTableDataRow } from '../../../types/all'
@@ -184,13 +184,9 @@ export default defineComponent({
184
184
  },
185
185
  // 存放数据校验相关信息
186
186
  validStore: {
187
- visible: false,
188
- row: null,
189
- column: null,
190
- content: '',
191
- rule: null,
192
- isArrow: false
187
+ visible: false
193
188
  },
189
+ validErrorMaps: {},
194
190
  // 导入相关信息
195
191
  importStore: {
196
192
  inited: false,
@@ -295,6 +291,7 @@ export default defineComponent({
295
291
  // 总的缓存数据集
296
292
  fullAllDataRowIdData: {},
297
293
  // 渲染中缓存数据
294
+ sourceDataRowIdData: {},
298
295
  fullDataRowIdData: {},
299
296
  fullColumnIdData: {},
300
297
  fullColumnFieldData: {},
@@ -504,6 +501,27 @@ export default defineComponent({
504
501
  return Object.assign({}, GlobalConfig.table.customConfig, props.customConfig)
505
502
  })
506
503
 
504
+ const computeFixedColumnSize = computed(() => {
505
+ const { tableFullColumn } = internalData
506
+ let fixedSize = 0
507
+ tableFullColumn.forEach((column) => {
508
+ if (column.fixed) {
509
+ fixedSize++
510
+ }
511
+ })
512
+ return fixedSize
513
+ })
514
+
515
+ const computeIsMaxFixedColumn = computed(() => {
516
+ const fixedColumnSize = computeFixedColumnSize.value
517
+ const columnOpts = computeColumnOpts.value
518
+ const { maxFixedSize } = columnOpts
519
+ if (maxFixedSize) {
520
+ return fixedColumnSize >= maxFixedSize
521
+ }
522
+ return false
523
+ })
524
+
507
525
  const computeTableBorder = computed(() => {
508
526
  const { border } = props
509
527
  if (border === true) {
@@ -590,6 +608,8 @@ export default defineComponent({
590
608
  computeEmptyOpts,
591
609
  computeLoadingOpts,
592
610
  computeCustomOpts,
611
+ computeFixedColumnSize,
612
+ computeIsMaxFixedColumn,
593
613
  computeIsAllCheckboxDisabled
594
614
  }
595
615
 
@@ -847,6 +867,7 @@ export default defineComponent({
847
867
  resizeWidth?: number
848
868
  visible?: boolean
849
869
  fixed?: string
870
+ order?: number
850
871
  }
851
872
  } = {}
852
873
  if (!id) {
@@ -857,8 +878,8 @@ export default defineComponent({
857
878
  if (isCustomResizable) {
858
879
  const columnWidthStorage = getCustomStorageMap(resizableStorageKey)[id]
859
880
  if (columnWidthStorage) {
860
- XEUtils.each(columnWidthStorage, (resizeWidth: number, field) => {
861
- customMap[field] = { field, resizeWidth }
881
+ XEUtils.each(columnWidthStorage, (resizeWidth: number, colKey) => {
882
+ customMap[colKey] = { resizeWidth }
862
883
  })
863
884
  }
864
885
  }
@@ -868,11 +889,11 @@ export default defineComponent({
868
889
  if (columnFixedStorage) {
869
890
  const colFixeds = columnFixedStorage.split(',')
870
891
  colFixeds.forEach((fixConf: any) => {
871
- const [field, fixed] = fixConf.split('|')
872
- if (customMap[field]) {
873
- customMap[field].fixed = fixed
892
+ const [colKey, fixed] = fixConf.split('|')
893
+ if (customMap[colKey]) {
894
+ customMap[colKey].fixed = fixed
874
895
  } else {
875
- customMap[field] = { field, fixed }
896
+ customMap[colKey] = { fixed }
876
897
  }
877
898
  })
878
899
  }
@@ -881,7 +902,15 @@ export default defineComponent({
881
902
  if (isCustomOrder) {
882
903
  const columnOrderStorage = getCustomStorageMap(orderStorageKey)[id]
883
904
  if (columnOrderStorage) {
884
- // 开发中...
905
+ // const colOrderSeqs = columnOrderStorage.split(',')
906
+ // colOrderSeqs.forEach((orderConf: any) => {
907
+ // const [colKey, order] = orderConf.split('|')
908
+ // if (customMap[colKey]) {
909
+ // customMap[colKey].order = order
910
+ // } else {
911
+ // customMap[colKey] = { order }
912
+ // }
913
+ // })
885
914
  }
886
915
  }
887
916
  // 自定义隐藏列
@@ -891,18 +920,18 @@ export default defineComponent({
891
920
  const colVisibles = columnVisibleStorage.split('|')
892
921
  const colHides: string[] = colVisibles[0] ? colVisibles[0].split(',') : []
893
922
  const colShows: string[] = colVisibles[1] ? colVisibles[1].split(',') : []
894
- colHides.forEach((field) => {
895
- if (customMap[field]) {
896
- customMap[field].visible = false
923
+ colHides.forEach((colKey) => {
924
+ if (customMap[colKey]) {
925
+ customMap[colKey].visible = false
897
926
  } else {
898
- customMap[field] = { field, visible: false }
927
+ customMap[colKey] = { visible: false }
899
928
  }
900
929
  })
901
- colShows.forEach((field) => {
902
- if (customMap[field]) {
903
- customMap[field].visible = true
930
+ colShows.forEach((colKey) => {
931
+ if (customMap[colKey]) {
932
+ customMap[colKey].visible = true
904
933
  } else {
905
- customMap[field] = { field, visible: true }
934
+ customMap[colKey] = { visible: true }
906
935
  }
907
936
  })
908
937
  }
@@ -916,8 +945,8 @@ export default defineComponent({
916
945
  keyMap[colKey] = column
917
946
  }
918
947
  })
919
- XEUtils.each(customMap, ({ visible, resizeWidth, fixed }, field) => {
920
- const column = keyMap[field]
948
+ XEUtils.each(customMap, ({ visible, resizeWidth, fixed, order }, colKey) => {
949
+ const column = keyMap[colKey]
921
950
  if (column) {
922
951
  if (XEUtils.isNumber(resizeWidth)) {
923
952
  column.resizeWidth = resizeWidth
@@ -928,6 +957,9 @@ export default defineComponent({
928
957
  if (fixed) {
929
958
  column.fixed = fixed
930
959
  }
960
+ if (order) {
961
+ column.customOrder = order
962
+ }
931
963
  }
932
964
  })
933
965
  }
@@ -2161,7 +2193,7 @@ export default defineComponent({
2161
2193
  internalData.tableSynchData = datas
2162
2194
  // 克隆原数据,用于显示编辑状态,与编辑值做对比
2163
2195
  if (keepSource) {
2164
- internalData.tableSourceData = XEUtils.clone(fullData, true)
2196
+ tablePrivateMethods.cacheSourceMap(fullData)
2165
2197
  }
2166
2198
  if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
2167
2199
  if (sYLoad) {
@@ -2912,33 +2944,22 @@ export default defineComponent({
2912
2944
  * @param {String} field 字段名
2913
2945
  */
2914
2946
  isUpdateByRow (row, field) {
2915
- const { keepSource, treeConfig } = props
2916
- const { visibleColumn, tableSourceData, fullDataRowIdData } = internalData
2917
- const treeOpts = computeTreeOpts.value
2947
+ const { keepSource } = props
2948
+ const { tableFullColumn, fullDataRowIdData, sourceDataRowIdData } = internalData
2918
2949
  if (keepSource) {
2919
- let oRow, property
2920
2950
  const rowid = getRowid($xetable, row)
2921
2951
  // 新增的数据不需要检测
2922
2952
  if (!fullDataRowIdData[rowid]) {
2923
2953
  return false
2924
2954
  }
2925
- if (treeConfig) {
2926
- const children = treeOpts.children
2927
- const matchObj = XEUtils.findTree(tableSourceData, item => rowid === getRowid($xetable, item), treeOpts)
2928
- row = Object.assign({}, row, { [children]: null })
2929
- if (matchObj) {
2930
- oRow = Object.assign({}, matchObj.item, { [children]: null })
2931
- }
2932
- } else {
2933
- const oRowIndex = fullDataRowIdData[rowid].index
2934
- oRow = tableSourceData[oRowIndex]
2935
- }
2936
- if (oRow) {
2955
+ const oldRest = sourceDataRowIdData[rowid]
2956
+ if (oldRest) {
2957
+ const oRow = oldRest.row
2937
2958
  if (arguments.length > 1) {
2938
2959
  return !eqCellValue(oRow, row, field as string)
2939
2960
  }
2940
- for (let index = 0, len = visibleColumn.length; index < len; index++) {
2941
- property = visibleColumn[index].field
2961
+ for (let index = 0, len = tableFullColumn.length; index < len; index++) {
2962
+ const property = tableFullColumn[index].field
2942
2963
  if (property && !eqCellValue(oRow, row, property)) {
2943
2964
  return true
2944
2965
  }
@@ -3073,8 +3094,20 @@ export default defineComponent({
3073
3094
  */
3074
3095
  setColumnFixed (fieldOrColumn, fixed) {
3075
3096
  const column = handleFieldOrColumn($xetable, fieldOrColumn)
3076
- if (column && column.fixed !== fixed) {
3077
- XEUtils.eachTree([column], (column) => {
3097
+ const targetColumn = getRootColumn($xetable, column as any)
3098
+ const isMaxFixedColumn = computeIsMaxFixedColumn.value
3099
+ if (targetColumn && targetColumn.fixed !== fixed) {
3100
+ // 是否超过最大固定列数量
3101
+ if (!targetColumn.fixed && isMaxFixedColumn) {
3102
+ if (VXETable.modal) {
3103
+ VXETable.modal.message({
3104
+ status: 'error',
3105
+ content: GlobalConfig.i18n('vxe.table.maxFixedCol')
3106
+ })
3107
+ }
3108
+ return nextTick()
3109
+ }
3110
+ XEUtils.eachTree([targetColumn], (column) => {
3078
3111
  column.fixed = fixed
3079
3112
  })
3080
3113
  tablePrivateMethods.saveCustomFixed()
@@ -3087,8 +3120,9 @@ export default defineComponent({
3087
3120
  */
3088
3121
  clearColumnFixed (fieldOrColumn) {
3089
3122
  const column = handleFieldOrColumn($xetable, fieldOrColumn)
3090
- if (column && column.fixed) {
3091
- XEUtils.eachTree([column], (column) => {
3123
+ const targetColumn = getRootColumn($xetable, column as any)
3124
+ if (targetColumn && targetColumn.fixed) {
3125
+ XEUtils.eachTree([targetColumn], (column) => {
3092
3126
  column.fixed = null
3093
3127
  })
3094
3128
  tablePrivateMethods.saveCustomFixed()
@@ -3146,7 +3180,7 @@ export default defineComponent({
3146
3180
  * 如果已关联工具栏,则会同步更新
3147
3181
  */
3148
3182
  resetColumn (options) {
3149
- const { tableFullColumn } = internalData
3183
+ const { collectColumn } = internalData
3150
3184
  const customOpts = computeCustomOpts.value
3151
3185
  const { checkMethod } = customOpts
3152
3186
  const opts = Object.assign({
@@ -3154,7 +3188,7 @@ export default defineComponent({
3154
3188
  resizable: options === true,
3155
3189
  fixed: options === true
3156
3190
  }, options)
3157
- tableFullColumn.forEach((column) => {
3191
+ XEUtils.eachTree(collectColumn, (column) => {
3158
3192
  if (opts.resizable) {
3159
3193
  column.resizeWidth = 0
3160
3194
  }
@@ -4071,7 +4105,7 @@ export default defineComponent({
4071
4105
  if (customVal && validStore.visible) {
4072
4106
  setCellValue(row, column, cellValue)
4073
4107
  }
4074
- $xetable.clearValidate()
4108
+ $xetable.clearValidate(row, column)
4075
4109
  })
4076
4110
  .catch(({ rule }) => {
4077
4111
  if (customVal) {
@@ -4803,7 +4837,7 @@ export default defineComponent({
4803
4837
  let { fullDataRowIdData, fullAllDataRowIdData, tableFullData, tableFullTreeData } = internalData
4804
4838
  const rowkey = getRowkey($xetable)
4805
4839
  const isLazy = treeConfig && treeOpts.lazy
4806
- const handleCache = (row: any, index: any, items: any, path?: any[], parent?: any, nodes?: any[]) => {
4840
+ const handleRow = (row: any, index: any, items: any, path?: any[], parent?: any, nodes?: any[]) => {
4807
4841
  let rowid = getRowid($xetable, row)
4808
4842
  const seq = treeConfig && path ? toTreePathSeq(path) : index + 1
4809
4843
  const level = nodes ? nodes.length - 1 : 0
@@ -4825,10 +4859,36 @@ export default defineComponent({
4825
4859
  }
4826
4860
  fullAllDataRowIdData = internalData.fullAllDataRowIdData = {}
4827
4861
  if (treeConfig) {
4828
- XEUtils.eachTree(tableFullTreeData, handleCache, treeOpts)
4862
+ XEUtils.eachTree(tableFullTreeData, handleRow, treeOpts)
4863
+ } else {
4864
+ tableFullData.forEach(handleRow)
4865
+ }
4866
+ },
4867
+ cacheSourceMap (fullData) {
4868
+ const { treeConfig } = props
4869
+ const treeOpts = computeTreeOpts.value
4870
+ let { sourceDataRowIdData } = internalData
4871
+ const sourceData = XEUtils.clone(fullData, true)
4872
+ const rowkey = getRowkey($xetable)
4873
+ sourceDataRowIdData = internalData.sourceDataRowIdData = {}
4874
+ const handleSourceRow = (row: any) => {
4875
+ let rowid = getRowid($xetable, row)
4876
+ if (eqEmptyValue(rowid)) {
4877
+ rowid = getRowUniqueId()
4878
+ XEUtils.set(row, rowkey, rowid)
4879
+ }
4880
+ sourceDataRowIdData[rowid] = {
4881
+ row,
4882
+ rowid
4883
+ }
4884
+ }
4885
+ // 源数据缓存
4886
+ if (treeConfig && !treeOpts.transform) {
4887
+ XEUtils.eachTree(sourceData, handleSourceRow, treeOpts)
4829
4888
  } else {
4830
- tableFullData.forEach(handleCache)
4889
+ sourceData.forEach(handleSourceRow)
4831
4890
  }
4891
+ internalData.tableSourceData = sourceData
4832
4892
  },
4833
4893
  /**
4834
4894
  * 指定列宽的列进行拆分
@@ -248,6 +248,23 @@ export function destroyColumn ($xetable: VxeTableConstructor & VxeTablePrivateMe
248
248
  reactData.staticColumns = staticColumns.slice(0)
249
249
  }
250
250
 
251
+ export function getRootColumn ($xetable: VxeTableConstructor & VxeTablePrivateMethods, column: ColumnInfo) {
252
+ const { internalData } = $xetable
253
+ const { fullColumnIdData } = internalData
254
+ if (!column) {
255
+ return null
256
+ }
257
+ let parentColId = column.parentId
258
+ while (fullColumnIdData[parentColId]) {
259
+ const column = fullColumnIdData[parentColId].column
260
+ parentColId = column.parentId
261
+ if (!parentColId) {
262
+ return column
263
+ }
264
+ }
265
+ return column
266
+ }
267
+
251
268
  export function mergeBodyMethod (mergeList: VxeTableDefines.MergeItem[], _rowIndex: number, _columnIndex: number) {
252
269
  for (let mIndex = 0; mIndex < mergeList.length; mIndex++) {
253
270
  const { row: mergeRowIndex, col: mergeColIndex, rowspan: mergeRowspan, colspan: mergeColspan } = mergeList[mIndex]
@@ -9,7 +9,7 @@ import { warnLog, errLog } from '../../tools/log'
9
9
  import { GlobalEvent } from '../../tools/event'
10
10
  import { getSlotVNs } from '../../tools/vn'
11
11
 
12
- import { VxeGridConstructor, GridPrivateMethods, ToolbarMethods, VxeToolbarConstructor, VxeToolbarEmits, VxeToolbarPropTypes, VxeTableConstructor, ToolbarPrivateRef, VxeTableMethods, VxeTablePrivateMethods, ToolbarReactData, VxeTableDefines } from '../../../types/all'
12
+ import { VxeGridConstructor, GridPrivateMethods, ToolbarMethods, VxeToolbarConstructor, VxeToolbarEmits, VxeToolbarPropTypes, VxeTableConstructor, ToolbarPrivateRef, VxeTableMethods, VxeTablePrivateMethods, ToolbarReactData, VxeTableDefines, VxeColumnPropTypes } from '../../../types/all'
13
13
 
14
14
  export default defineComponent({
15
15
  name: 'VxeToolbar',
@@ -176,7 +176,7 @@ export default defineComponent({
176
176
  }
177
177
  }
178
178
 
179
- const changeCustomOption = (column: VxeTableDefines.ColumnInfo) => {
179
+ const changeCheckboxOption = (column: VxeTableDefines.ColumnInfo) => {
180
180
  const isChecked = !column.visible
181
181
  const customOpts = computeCustomOpts.value
182
182
  XEUtils.eachTree([column], (item) => {
@@ -190,6 +190,18 @@ export default defineComponent({
190
190
  checkCustomStatus()
191
191
  }
192
192
 
193
+ const changeFixedOption = (column: VxeTableDefines.ColumnInfo, colFixed: VxeColumnPropTypes.Fixed) => {
194
+ const { computeIsMaxFixedColumn } = $xetable.getComputeMaps()
195
+ const isMaxFixedColumn = computeIsMaxFixedColumn.value
196
+ if (column.fixed === colFixed) {
197
+ $xetable.clearColumnFixed(column)
198
+ } else {
199
+ if (!isMaxFixedColumn || column.fixed) {
200
+ $xetable.setColumnFixed(column, colFixed)
201
+ }
202
+ }
203
+ }
204
+
193
205
  const allCustomEvent = () => {
194
206
  const { columns } = reactData
195
207
  const { computeCustomOpts: computeTableCustomOpts } = $xetable.getComputeMaps()
@@ -458,6 +470,7 @@ export default defineComponent({
458
470
  const renderCustoms = () => {
459
471
  const { columns } = reactData
460
472
  const customOpts = computeCustomOpts.value
473
+ let isMaxFixedColumn = true
461
474
  const colVNs: VNode[] = []
462
475
  const customBtnOns: {
463
476
  onClick?: typeof handleClickSettingEvent;
@@ -470,9 +483,10 @@ export default defineComponent({
470
483
  } = {}
471
484
  let checkMethod: ((params: { column: VxeTableDefines.ColumnInfo }) => boolean) | undefined
472
485
  if ($xetable) {
473
- const { computeCustomOpts: computeTableCustomOpts } = $xetable.getComputeMaps()
486
+ const { computeCustomOpts: computeTableCustomOpts, computeIsMaxFixedColumn } = $xetable.getComputeMaps()
474
487
  const tableCustomOpts = computeTableCustomOpts.value
475
488
  checkMethod = tableCustomOpts.checkMethod
489
+ isMaxFixedColumn = computeIsMaxFixedColumn.value
476
490
  }
477
491
  if (customOpts.trigger === 'manual') {
478
492
  // 手动触发
@@ -486,7 +500,7 @@ export default defineComponent({
486
500
  // 点击触发
487
501
  customBtnOns.onClick = handleClickSettingEvent
488
502
  }
489
- XEUtils.eachTree(columns, (column) => {
503
+ XEUtils.eachTree(columns, (column, index, items, path, parent) => {
490
504
  const colTitle = formatText(column.getTitle(), 1)
491
505
  const colKey = column.getKey()
492
506
  const isColGroup = column.children && column.children.length
@@ -497,24 +511,53 @@ export default defineComponent({
497
511
  colVNs.push(
498
512
  h('li', {
499
513
  class: ['vxe-custom--option', `level--${column.level}`, {
500
- 'is--group': isColGroup,
501
- 'is--checked': isChecked,
502
- 'is--indeterminate': isIndeterminate,
503
- 'is--disabled': isDisabled
504
- }],
505
- title: colTitle,
506
- onClick: () => {
507
- if (!isDisabled) {
508
- changeCustomOption(column)
509
- }
510
- }
514
+ 'is--group': isColGroup
515
+ }]
511
516
  }, [
512
- h('span', {
513
- class: ['vxe-checkbox--icon', isIndeterminate ? GlobalConfig.icon.TABLE_CHECKBOX_INDETERMINATE : (isChecked ? GlobalConfig.icon.TABLE_CHECKBOX_CHECKED : GlobalConfig.icon.TABLE_CHECKBOX_UNCHECKED)]
514
- }),
515
- h('span', {
516
- class: 'vxe-checkbox--label'
517
- }, colTitle)
517
+ h('div', {
518
+ title: colTitle,
519
+ class: ['vxe-custom--checkbox-option', {
520
+ 'is--checked': isChecked,
521
+ 'is--indeterminate': isIndeterminate,
522
+ 'is--disabled': isDisabled
523
+ }],
524
+ onClick: () => {
525
+ if (!isDisabled) {
526
+ changeCheckboxOption(column)
527
+ }
528
+ }
529
+ }, [
530
+ h('span', {
531
+ class: ['vxe-checkbox--icon', isIndeterminate ? GlobalConfig.icon.TABLE_CHECKBOX_INDETERMINATE : (isChecked ? GlobalConfig.icon.TABLE_CHECKBOX_CHECKED : GlobalConfig.icon.TABLE_CHECKBOX_UNCHECKED)]
532
+ }),
533
+ h('span', {
534
+ class: 'vxe-checkbox--label'
535
+ }, colTitle)
536
+ ]),
537
+ !parent && customOpts.allowFixed ? h('div', {
538
+ class: 'vxe-custom--fixed-option'
539
+ }, [
540
+ h('span', {
541
+ class: ['vxe-custom--fixed-left-option', column.fixed === 'left' ? GlobalConfig.icon.TOOLBAR_TOOLS_FIXED_LEFT_ACTIVED : GlobalConfig.icon.TOOLBAR_TOOLS_FIXED_LEFT, {
542
+ 'is--checked': column.fixed === 'left',
543
+ 'is--disabled': isMaxFixedColumn && !column.fixed
544
+ }],
545
+ title: GlobalConfig.i18n(column.fixed === 'left' ? 'vxe.toolbar.cancelfixed' : 'vxe.toolbar.fixedLeft'),
546
+ onClick: () => {
547
+ changeFixedOption(column, 'left')
548
+ }
549
+ }),
550
+ h('span', {
551
+ class: ['vxe-custom--fixed-right-option', column.fixed === 'right' ? GlobalConfig.icon.TOOLBAR_TOOLS_FIXED_RIGHT_ACTIVED : GlobalConfig.icon.TOOLBAR_TOOLS_FIXED_RIGHT, {
552
+ 'is--checked': column.fixed === 'right',
553
+ 'is--disabled': isMaxFixedColumn && !column.fixed
554
+ }],
555
+ title: GlobalConfig.i18n(column.fixed === 'right' ? 'vxe.toolbar.cancelfixed' : 'vxe.toolbar.fixedRight'),
556
+ onClick: () => {
557
+ changeFixedOption(column, 'right')
558
+ }
559
+ })
560
+ ]) : null
518
561
  ])
519
562
  )
520
563
  }
@@ -540,37 +583,41 @@ export default defineComponent({
540
583
  class: 'vxe-custom--header'
541
584
  }, [
542
585
  h('li', {
543
- class: ['vxe-custom--option', {
544
- 'is--checked': isAllChecked,
545
- 'is--indeterminate': isAllIndeterminate
546
- }],
547
- title: GlobalConfig.i18n('vxe.table.allTitle'),
548
- onClick: allCustomEvent
586
+ class: 'vxe-custom--option'
549
587
  }, [
550
- h('span', {
551
- class: ['vxe-checkbox--icon', isAllIndeterminate ? GlobalConfig.icon.TABLE_CHECKBOX_INDETERMINATE : (isAllChecked ? GlobalConfig.icon.TABLE_CHECKBOX_CHECKED : GlobalConfig.icon.TABLE_CHECKBOX_UNCHECKED)]
552
- }),
553
- h('span', {
554
- class: 'vxe-checkbox--label'
555
- }, GlobalConfig.i18n('vxe.toolbar.customAll'))
588
+ h('div', {
589
+ class: ['vxe-custom--checkbox-option', {
590
+ 'is--checked': isAllChecked,
591
+ 'is--indeterminate': isAllIndeterminate
592
+ }],
593
+ title: GlobalConfig.i18n('vxe.table.allTitle'),
594
+ onClick: allCustomEvent
595
+ }, [
596
+ h('span', {
597
+ class: ['vxe-checkbox--icon', isAllIndeterminate ? GlobalConfig.icon.TABLE_CHECKBOX_INDETERMINATE : (isAllChecked ? GlobalConfig.icon.TABLE_CHECKBOX_CHECKED : GlobalConfig.icon.TABLE_CHECKBOX_UNCHECKED)]
598
+ }),
599
+ h('span', {
600
+ class: 'vxe-checkbox--label'
601
+ }, GlobalConfig.i18n('vxe.toolbar.customAll'))
602
+ ])
556
603
  ])
557
604
  ]),
558
605
  h('ul', {
559
606
  class: 'vxe-custom--body',
560
607
  ...customWrapperOns
561
608
  }, colVNs),
562
- customOpts.isFooter === false ? null : h('div', {
609
+ customOpts.showFooter || customOpts.isFooter ? h('div', {
563
610
  class: 'vxe-custom--footer'
564
611
  }, [
565
- h('button', {
566
- class: 'btn--confirm',
567
- onClick: confirmCustomEvent
568
- }, GlobalConfig.i18n('vxe.toolbar.customConfirm')),
569
612
  h('button', {
570
613
  class: 'btn--reset',
571
614
  onClick: resetCustomEvent
572
- }, GlobalConfig.i18n('vxe.toolbar.customRestore'))
573
- ])
615
+ }, customOpts.resetButtonText || GlobalConfig.i18n('vxe.toolbar.customRestore')),
616
+ h('button', {
617
+ class: 'btn--confirm',
618
+ onClick: confirmCustomEvent
619
+ }, customOpts.confirmButtonText || GlobalConfig.i18n('vxe.toolbar.customConfirm'))
620
+ ]) : null
574
621
  ])
575
622
  ])
576
623
  }
@@ -50,6 +50,9 @@ const GlobalConfig: VXETableGlobalConfig = {
50
50
  showMessage: true,
51
51
  message: 'default'
52
52
  },
53
+ columnConfig: {
54
+ maxFixedSize: 4
55
+ },
53
56
  // menuConfig: {
54
57
  // visibleMethod () {}
55
58
  // },
@@ -196,6 +199,10 @@ const GlobalConfig: VXETableGlobalConfig = {
196
199
  TOOLBAR_TOOLS_FULLSCREEN: iconPrefix + 'fullscreen',
197
200
  TOOLBAR_TOOLS_MINIMIZE: iconPrefix + 'minimize',
198
201
  TOOLBAR_TOOLS_CUSTOM: iconPrefix + 'custom-column',
202
+ TOOLBAR_TOOLS_FIXED_LEFT: iconPrefix + 'fixed-left',
203
+ TOOLBAR_TOOLS_FIXED_LEFT_ACTIVED: iconPrefix + 'fixed-left-fill',
204
+ TOOLBAR_TOOLS_FIXED_RIGHT: iconPrefix + 'fixed-right',
205
+ TOOLBAR_TOOLS_FIXED_RIGHT_ACTIVED: iconPrefix + 'fixed-right-fill',
199
206
 
200
207
  // form
201
208
  FORM_PREFIX: iconPrefix + 'question-circle-fill',
@@ -304,9 +311,10 @@ const GlobalConfig: VXETableGlobalConfig = {
304
311
  // export: {
305
312
  // types: ['csv', 'html', 'xml', 'txt']
306
313
  // },
307
- // custom: {
308
- // isFooter: true
309
- // },
314
+ custom: {
315
+ allowFixed: true,
316
+ showFooter: true
317
+ }
310
318
  // buttons: []
311
319
  },
312
320
  button: {