vxe-table 4.16.20 → 4.17.0-beta.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 (78) hide show
  1. package/README.md +2 -0
  2. package/es/grid/src/grid.js +8 -0
  3. package/es/index.css +1 -1
  4. package/es/index.min.css +1 -1
  5. package/es/style.css +1 -1
  6. package/es/style.min.css +1 -1
  7. package/es/table/module/filter/hook.js +109 -59
  8. package/es/table/module/filter/panel.js +46 -26
  9. package/es/table/render/index.js +93 -9
  10. package/es/table/src/column.js +2 -0
  11. package/es/table/src/columnInfo.js +14 -6
  12. package/es/table/src/header.js +118 -3
  13. package/es/table/src/props.js +2 -0
  14. package/es/table/src/table.js +31 -28
  15. package/es/table/src/util.js +8 -5
  16. package/es/table/style.css +2 -1
  17. package/es/table/style.min.css +1 -1
  18. package/es/ui/index.js +4 -1
  19. package/es/ui/src/log.js +1 -1
  20. package/es/ui/src/vn.js +11 -0
  21. package/es/vxe-table/style.css +2 -1
  22. package/es/vxe-table/style.min.css +1 -1
  23. package/lib/grid/src/grid.js +12 -0
  24. package/lib/grid/src/grid.min.js +1 -1
  25. package/lib/index.css +1 -1
  26. package/lib/index.min.css +1 -1
  27. package/lib/index.umd.js +513 -136
  28. package/lib/index.umd.min.js +1 -1
  29. package/lib/style.css +1 -1
  30. package/lib/style.min.css +1 -1
  31. package/lib/table/module/filter/hook.js +124 -67
  32. package/lib/table/module/filter/hook.min.js +1 -1
  33. package/lib/table/module/filter/panel.js +60 -26
  34. package/lib/table/module/filter/panel.min.js +1 -1
  35. package/lib/table/render/index.js +109 -8
  36. package/lib/table/render/index.min.js +1 -1
  37. package/lib/table/src/column.js +2 -0
  38. package/lib/table/src/column.min.js +1 -1
  39. package/lib/table/src/columnInfo.js +18 -5
  40. package/lib/table/src/columnInfo.min.js +1 -1
  41. package/lib/table/src/header.js +133 -3
  42. package/lib/table/src/header.min.js +1 -1
  43. package/lib/table/src/props.js +2 -0
  44. package/lib/table/src/props.min.js +1 -1
  45. package/lib/table/src/table.js +11 -11
  46. package/lib/table/src/table.min.js +1 -1
  47. package/lib/table/src/util.js +18 -14
  48. package/lib/table/src/util.min.js +1 -1
  49. package/lib/table/style/style.css +2 -1
  50. package/lib/table/style/style.min.css +1 -1
  51. package/lib/ui/index.js +4 -1
  52. package/lib/ui/index.min.js +1 -1
  53. package/lib/ui/src/log.js +1 -1
  54. package/lib/ui/src/log.min.js +1 -1
  55. package/lib/ui/src/vn.js +12 -0
  56. package/lib/ui/src/vn.min.js +1 -1
  57. package/lib/vxe-table/style/style.css +2 -1
  58. package/lib/vxe-table/style/style.min.css +1 -1
  59. package/package.json +1 -1
  60. package/packages/grid/src/grid.ts +8 -0
  61. package/packages/table/module/filter/hook.ts +111 -65
  62. package/packages/table/module/filter/panel.ts +57 -29
  63. package/packages/table/render/index.ts +110 -15
  64. package/packages/table/src/column.ts +2 -0
  65. package/packages/table/src/columnInfo.ts +19 -7
  66. package/packages/table/src/header.ts +137 -8
  67. package/packages/table/src/props.ts +2 -0
  68. package/packages/table/src/table.ts +32 -28
  69. package/packages/table/src/util.ts +8 -5
  70. package/packages/ui/index.ts +3 -0
  71. package/packages/ui/src/vn.ts +12 -0
  72. package/styles/components/table-module/filter.scss +4 -1
  73. /package/es/{iconfont.1758850674944.ttf → iconfont.1759043328183.ttf} +0 -0
  74. /package/es/{iconfont.1758850674944.woff → iconfont.1759043328183.woff} +0 -0
  75. /package/es/{iconfont.1758850674944.woff2 → iconfont.1759043328183.woff2} +0 -0
  76. /package/lib/{iconfont.1758850674944.ttf → iconfont.1759043328183.ttf} +0 -0
  77. /package/lib/{iconfont.1758850674944.woff → iconfont.1759043328183.woff} +0 -0
  78. /package/lib/{iconfont.1758850674944.woff2 → iconfont.1759043328183.woff2} +0 -0
@@ -3,10 +3,10 @@ import XEUtils from 'xe-utils'
3
3
  import { VxeUI } from '../../ui'
4
4
  import { getCellValue, setCellValue } from '../../table/src/util'
5
5
  import { getFuncText, formatText, isEmptyValue } from '../../ui/src/utils'
6
- import { getOnName, getModelEvent, getChangeEvent } from '../../ui/src/vn'
6
+ import { getOnName, getModelEvent, getChangeEvent, hasInputType } from '../../ui/src/vn'
7
7
  import { errLog } from '../../ui/src/log'
8
8
 
9
- import type { VxeGlobalRendererHandles, VxeColumnPropTypes, VxeTableConstructor, VxeTablePrivateMethods } from '../../../types'
9
+ import type { VxeGlobalRendererHandles, VxeColumnPropTypes, VxeTableConstructor, VxeTablePrivateMethods, VxeTableDefines } from '../../../types'
10
10
 
11
11
  const { getConfig, renderer, getI18n, getComponent } = VxeUI
12
12
 
@@ -51,9 +51,14 @@ function getOldComponent ({ name }: any) {
51
51
  return resolveComponent(getOldComponentName(name)) as ComponentOptions
52
52
  }
53
53
 
54
- function handleConfirmFilter (params: any, checked: any, option: any) {
55
- const { $panel } = params
56
- $panel.changeOption({}, checked, option)
54
+ function updateFilterChangeOption (params: VxeGlobalRendererHandles.RenderTableFilterParams | VxeGlobalRendererHandles.RenderTableFloatingFilterParams, checked: boolean, option: VxeTableDefines.FilterOption) {
55
+ const { $table } = params
56
+ $table.updateFilterOptionStatus(option, checked)
57
+ }
58
+
59
+ function saveFilterEvent (params: VxeGlobalRendererHandles.RenderTableFilterParams | VxeGlobalRendererHandles.RenderTableFloatingFilterParams) {
60
+ const { $table, column } = params
61
+ $table.saveFilterByEvent(new Event('change'), column)
57
62
  }
58
63
 
59
64
  function getNativeAttrs (renderOpts: VxeGlobalRendererHandles.RenderTableCellOptions) {
@@ -164,6 +169,7 @@ function getNativeElementOns (renderOpts: VxeGlobalRendererHandles.RenderTableCe
164
169
  }
165
170
 
166
171
  const blurEvent = 'blur'
172
+ const clearEvent = 'clear'
167
173
 
168
174
  /**
169
175
  * 组件事件处理
@@ -176,11 +182,12 @@ function getComponentOns (renderOpts: VxeGlobalRendererHandles.RenderTableCellOp
176
182
  model: (cellValue: any) => void
177
183
  change?: (...args: any[]) => void
178
184
  blur?: (...args: any[]) => void
185
+ clear?: (...args: any[]) => void
179
186
  }, eventOns?: Record<string, any>) {
180
187
  const { events } = renderOpts
181
188
  const modelEvent = getModelEvent(renderOpts)
182
189
  const changeEvent = getChangeEvent(renderOpts)
183
- const { model: modelFunc, change: changeFunc, blur: blurFunc } = eFns || {}
190
+ const { model: modelFunc, change: changeFunc, blur: blurFunc, clear: clearFunc } = eFns || {}
184
191
  const ons: any = {}
185
192
  XEUtils.objectEach(events, (func, key: any) => {
186
193
  ons[getOnName(key)] = function (...args: any[]) {
@@ -214,6 +221,14 @@ function getComponentOns (renderOpts: VxeGlobalRendererHandles.RenderTableCellOp
214
221
  }
215
222
  }
216
223
  }
224
+ if (clearFunc) {
225
+ ons[getOnName(clearEvent)] = function (...args: any[]) {
226
+ clearFunc(...args)
227
+ if (events && events[clearEvent]) {
228
+ events[clearEvent](params, ...args)
229
+ }
230
+ }
231
+ }
217
232
  return eventOns ? Object.assign(ons, eventOns) : ons
218
233
  }
219
234
 
@@ -252,17 +267,64 @@ function getEditOns (renderOpts: VxeGlobalRendererHandles.RenderTableEditOptions
252
267
  })
253
268
  }
254
269
 
255
- function getFilterOns (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: any, option: any) {
270
+ function getFilterOns (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: VxeGlobalRendererHandles.RenderTableFilterParams, option: VxeTableDefines.FilterOption) {
256
271
  return getComponentOns(renderOpts, params, {
257
272
  model (value: any) {
258
273
  // 处理 model 值双向绑定
259
274
  option.data = value
260
275
  },
261
276
  change () {
262
- handleConfirmFilter(params, !XEUtils.eqNull(option.data), option)
277
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
263
278
  },
264
279
  blur () {
265
- handleConfirmFilter(params, !XEUtils.eqNull(option.data), option)
280
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
281
+ }
282
+ })
283
+ }
284
+
285
+ function getFloatingFilterOns (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: VxeGlobalRendererHandles.RenderTableFloatingFilterParams, option: VxeTableDefines.FilterOption) {
286
+ const { $table, column } = params
287
+ if (hasInputType(renderOpts)) {
288
+ return getComponentOns(renderOpts, params, {
289
+ model (value: any) {
290
+ // 处理 model 值双向绑定
291
+ option.data = value
292
+ },
293
+ change () {
294
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
295
+ },
296
+ clear () {
297
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
298
+ saveFilterEvent(params)
299
+ },
300
+ blur () {
301
+ $table.saveFilterByEvent(new Event('change'), column)
302
+ }
303
+ }, renderOpts.name === 'VxeNumberInput'
304
+ ? {
305
+ [getOnName('plus-number')] () {
306
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
307
+ saveFilterEvent(params)
308
+ },
309
+ [getOnName('minus-number')] () {
310
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
311
+ saveFilterEvent(params)
312
+ }
313
+ }
314
+ : {})
315
+ }
316
+ return getComponentOns(renderOpts, params, {
317
+ model (value: any) {
318
+ // 处理 model 值双向绑定
319
+ option.data = value
320
+ },
321
+ clear () {
322
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
323
+ $table.saveFilterByEvent(new Event('change'), column)
324
+ },
325
+ change () {
326
+ updateFilterChangeOption(params, !isEmptyValue(option.data), option)
327
+ $table.saveFilterByEvent(new Event('change'), column)
266
328
  }
267
329
  })
268
330
  }
@@ -312,10 +374,10 @@ function getNativeFilterOns (renderOpts: VxeGlobalRendererHandles.RenderTableFil
312
374
  }
313
375
  },
314
376
  change () {
315
- handleConfirmFilter(params, !XEUtils.eqNull(option.data), option)
377
+ updateFilterChangeOption(params, !XEUtils.eqNull(option.data), option)
316
378
  },
317
379
  blur () {
318
- handleConfirmFilter(params, !XEUtils.eqNull(option.data), option)
380
+ updateFilterChangeOption(params, !XEUtils.eqNull(option.data), option)
319
381
  }
320
382
  })
321
383
  }
@@ -458,11 +520,11 @@ function renderNativeOptions (options: any, renderOpts: VxeGlobalRendererHandles
458
520
  return []
459
521
  }
460
522
 
461
- function nativeFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: any) {
523
+ function nativeFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: VxeGlobalRendererHandles.RenderTableFilterParams) {
462
524
  const { column } = params
463
525
  const { name } = renderOpts
464
526
  const attrs = getNativeAttrs(renderOpts)
465
- return column.filters.map((option: any, oIndex: any) => {
527
+ return column.filters.map((option, oIndex) => {
466
528
  return h(`${name}`, {
467
529
  key: oIndex,
468
530
  class: `vxe-default-${name}`,
@@ -473,9 +535,9 @@ function nativeFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFil
473
535
  })
474
536
  }
475
537
 
476
- function defaultFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: any) {
538
+ function defaultFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFilterOptions, params: VxeGlobalRendererHandles.RenderTableFilterParams) {
477
539
  const { column } = params
478
- return column.filters.map((option: any, oIndex: any) => {
540
+ return column.filters.map((option, oIndex) => {
479
541
  const optionValue = option.data
480
542
  return h(getDefaultComponent(renderOpts), {
481
543
  key: oIndex,
@@ -485,6 +547,23 @@ function defaultFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFi
485
547
  })
486
548
  }
487
549
 
550
+ function defaultFloatingFilterRender (renderOpts: VxeGlobalRendererHandles.RenderTableFloatingFilterOptions, params: VxeGlobalRendererHandles.RenderTableFloatingFilterParams) {
551
+ const { option } = params
552
+ const optionValue = option.data
553
+ return [
554
+ h(getDefaultComponent(renderOpts), {
555
+ ...getCellEditFilterProps(renderOpts, renderOpts, optionValue),
556
+ ...getFloatingFilterOns(renderOpts, params, option)
557
+ })
558
+ ]
559
+ }
560
+
561
+ function defaultFilterOptions () {
562
+ return [
563
+ { data: null }
564
+ ]
565
+ }
566
+
488
567
  /**
489
568
  * 已废弃
490
569
  * @deprecated
@@ -744,7 +823,9 @@ renderer.mixin({
744
823
  return getCellLabelVNs(renderOpts, params, cellValue)
745
824
  },
746
825
  renderTableDefault: defaultEditRender,
826
+ createTableFilterOptions: defaultFilterOptions,
747
827
  renderTableFilter: defaultFilterRender,
828
+ renderTableFloatingFilter: defaultFloatingFilterRender,
748
829
  tableFilterDefaultMethod: handleInputFilterMethod
749
830
  },
750
831
  FormatNumberInput: {
@@ -797,7 +878,9 @@ renderer.mixin({
797
878
  return getFuncText(itemValue, 1)
798
879
  },
799
880
  renderTableDefault: defaultEditRender,
881
+ createTableFilterOptions: defaultFilterOptions,
800
882
  renderTableFilter: defaultFilterRender,
883
+ renderTableFloatingFilter: defaultFloatingFilterRender,
801
884
  tableFilterDefaultMethod: handleInputFilterMethod,
802
885
  tableExportMethod (params) {
803
886
  const { row, column } = params
@@ -820,7 +903,9 @@ renderer.mixin({
820
903
  return getCellLabelVNs(renderOpts, params, cellValue)
821
904
  },
822
905
  renderTableDefault: defaultEditRender,
906
+ createTableFilterOptions: defaultFilterOptions,
823
907
  renderTableFilter: defaultFilterRender,
908
+ renderTableFloatingFilter: defaultFloatingFilterRender,
824
909
  tableFilterDefaultMethod: handleFilterMethod
825
910
  },
826
911
  VxeDateRangePicker: {
@@ -924,6 +1009,7 @@ renderer.mixin({
924
1009
  renderTableCell (renderOpts, params) {
925
1010
  return getCellLabelVNs(renderOpts, params, getSelectCellValue(renderOpts, params))
926
1011
  },
1012
+ createTableFilterOptions: defaultFilterOptions,
927
1013
  renderTableFilter (renderOpts, params) {
928
1014
  const { column } = params
929
1015
  const { options, optionProps, optionGroups, optionGroupProps } = renderOpts
@@ -936,6 +1022,15 @@ renderer.mixin({
936
1022
  })
937
1023
  })
938
1024
  },
1025
+ renderTableFloatingFilter (renderOpts, params) {
1026
+ const { option } = params
1027
+ const { options, optionProps, optionGroups, optionGroupProps } = renderOpts
1028
+ const optionValue = option.data
1029
+ return h(getDefaultComponent(renderOpts), {
1030
+ ...getCellEditFilterProps(renderOpts, params, optionValue, { options, optionProps, optionGroups, optionGroupProps }),
1031
+ ...getFloatingFilterOns(renderOpts, params, option)
1032
+ })
1033
+ },
939
1034
  tableFilterDefaultMethod: handleFilterMethod,
940
1035
  tableExportMethod: handleExportSelectMethod
941
1036
  },
@@ -94,6 +94,8 @@ export const columnProps = {
94
94
  filterRecoverMethod: Function as PropType<VxeColumnPropTypes.FilterRecoverMethod>,
95
95
  // 筛选模板配置项
96
96
  filterRender: Object as PropType<VxeColumnPropTypes.FilterRender>,
97
+ // 是否显示浮动筛选
98
+ floatingFilters: Object as PropType<VxeColumnPropTypes.FloatingFilters>,
97
99
  // 设置为分组节点
98
100
  rowGroupNode: Boolean as PropType<VxeColumnPropTypes.RowGroupNode>,
99
101
  // 设置为树节点
@@ -1,12 +1,13 @@
1
1
  import XEUtils from 'xe-utils'
2
2
  import { VxeUI } from '../../ui'
3
3
  import { toFilters } from './util'
4
- import { getFuncText } from '../../ui/src/utils'
4
+ import { isEnableConf, getFuncText } from '../../ui/src/utils'
5
5
  import { warnLog, errLog } from '../../ui/src/log'
6
6
 
7
- import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types'
7
+ import type { VxeTableConstructor, VxeTablePrivateMethods, VxeTableDefines } from '../../../types'
8
+
9
+ const { getI18n, formats, renderer } = VxeUI
8
10
 
9
- const { getI18n, formats } = VxeUI
10
11
  export class ColumnInfo {
11
12
  /* eslint-disable @typescript-eslint/no-use-before-define */
12
13
  constructor ($xeTable: VxeTableConstructor & VxeTablePrivateMethods, _vm: any, { renderHeader, renderCell, renderFooter, renderData }: any = {}) {
@@ -15,11 +16,18 @@ export class ColumnInfo {
15
16
  const $xeGantt = $xeTable.xeGantt
16
17
  const $xeGGWrapper = $xeGrid || $xeGantt
17
18
 
18
- const { field, editRender } = _vm
19
+ const { field, editRender, filterRender } = _vm
20
+
21
+ const colId = _vm.colId || XEUtils.uniqueId('col_')
19
22
 
20
23
  const formatter: string | any[] = _vm.formatter
21
24
  const visible = XEUtils.isBoolean(_vm.visible) ? _vm.visible : true
22
25
 
26
+ const flCompConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
27
+ const ctFilterOptions = flCompConf ? flCompConf.createTableFilterOptions : null
28
+
29
+ const filters = toFilters(_vm.filters, colId)
30
+
23
31
  const types = ['seq', 'checkbox', 'radio', 'expand', 'html']
24
32
  if (_vm.type && types.indexOf(_vm.type) === -1) {
25
33
  warnLog('vxe.error.errProp', [`type=${_vm.type}`, types.join(', ')])
@@ -94,12 +102,13 @@ export class ColumnInfo {
94
102
  sortable: _vm.sortable,
95
103
  sortBy: _vm.sortBy,
96
104
  sortType: _vm.sortType,
97
- filters: toFilters(_vm.filters),
105
+ filters: filters,
98
106
  filterMultiple: XEUtils.isBoolean(_vm.filterMultiple) ? _vm.filterMultiple : true,
99
107
  filterMethod: _vm.filterMethod,
100
108
  filterResetMethod: _vm.filterResetMethod,
101
109
  filterRecoverMethod: _vm.filterRecoverMethod,
102
- filterRender: _vm.filterRender,
110
+ filterRender: filterRender,
111
+ floatingFilters: _vm.floatingFilters,
103
112
  rowGroupNode: _vm.rowGroupNode,
104
113
  treeNode: _vm.treeNode,
105
114
  dragSort: _vm.dragSort,
@@ -118,7 +127,7 @@ export class ColumnInfo {
118
127
  // 自定义参数
119
128
  params: _vm.params,
120
129
  // 渲染属性
121
- id: _vm.colId || XEUtils.uniqueId('col_'),
130
+ id: colId,
122
131
  parentId: null,
123
132
  visible,
124
133
  // 内部属性(一旦被使用,将导致不可升级版本)
@@ -169,6 +178,9 @@ export class ColumnInfo {
169
178
  // 单元格插槽,只对 grid 有效
170
179
  slots: _vm.slots
171
180
  })
181
+ if (ctFilterOptions && (!filters || !filters.length)) {
182
+ (this as any).filters = toFilters(ctFilterOptions({ $table: $xeTable, column: this as unknown as VxeTableDefines.ColumnInfo }), colId)
183
+ }
172
184
  if ($xeGGWrapper) {
173
185
  const { computeProxyOpts } = $xeGGWrapper.getComputeMaps()
174
186
  const proxyOpts = computeProxyOpts.value
@@ -2,9 +2,11 @@ import { h, ref, Ref, PropType, inject, nextTick, watch, onMounted, onUnmounted
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils from 'xe-utils'
4
4
  import { VxeUI } from '../../ui'
5
+ import { isEnableConf } from '../../ui/src/utils'
5
6
  import { getCalcHeight, convertHeaderColumnToRows, convertHeaderToGridRows } from './util'
7
+ import { getSlotVNs } from '../../ui/src/vn'
6
8
 
7
- import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines, VxeColumnPropTypes } from '../../../types'
9
+ import type { VxeTablePrivateMethods, VxeTableConstructor, VxeTableMethods, VxeTableDefines } from '../../../types'
8
10
 
9
11
  const { renderer, renderEmptyElement } = VxeUI
10
12
 
@@ -42,7 +44,7 @@ export default defineVxeComponent({
42
44
  const $xeTable = inject('$xeTable', {} as VxeTableConstructor & VxeTableMethods & VxeTablePrivateMethods)
43
45
 
44
46
  const { xID, props: tableProps, reactData: tableReactData, internalData: tableInternalData } = $xeTable
45
- const { computeColumnOpts, computeColumnDragOpts, computeCellOpts, computeMouseOpts, computeHeaderCellOpts, computeDefaultRowHeight, computeVirtualXOpts } = $xeTable.getComputeMaps()
47
+ const { computeColumnOpts, computeColumnDragOpts, computeCellOpts, computeMouseOpts, computeHeaderCellOpts, computeDefaultRowHeight, computeVirtualXOpts, computeFloatingFilterOpts } = $xeTable.getComputeMaps()
46
48
 
47
49
  const headerColumn = ref<VxeTableDefines.ColumnInfo[][]>([])
48
50
 
@@ -103,9 +105,9 @@ export default defineVxeComponent({
103
105
  const showTooltip = headOverflow === true || headOverflow === 'tooltip'
104
106
  const hasEllipsis = showTitle || showTooltip || showEllipsis
105
107
  let hasFilter = false
106
- let firstFilterOption: VxeColumnPropTypes.FilterItem | null = null
108
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
107
109
  if (filters) {
108
- firstFilterOption = filters[0]
110
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
109
111
  hasFilter = filters.some((item) => item.checked)
110
112
  }
111
113
  const columnIndex = colRest.index
@@ -264,13 +266,127 @@ export default defineVxeComponent({
264
266
  })
265
267
  }
266
268
 
267
- const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][]) => {
269
+ const renderFilterRows = (isOptimizeMode: boolean, cols: VxeTableDefines.ColumnInfo[]) => {
270
+ const $xeGrid = $xeTable.xeGrid
271
+ const $xeGantt = $xeTable.xeGantt
272
+
268
273
  const { fixedType } = props
269
- const { headerRowClassName, headerRowStyle } = tableProps
274
+ const { showHeaderOverflow: allColumnHeaderOverflow, headerAlign: allHeaderAlign, align: allAlign } = tableProps
275
+ const { currentColumn, overflowX } = tableReactData
276
+ const { fullColumnIdData } = tableInternalData
277
+ const cellOpts = computeCellOpts.value
278
+ const defaultRowHeight = computeDefaultRowHeight.value
279
+ const headerCellOpts = computeHeaderCellOpts.value
280
+ const currCellHeight = getCalcHeight(headerCellOpts.height) || defaultRowHeight
270
281
 
271
- return headerGroups.map((cols, $rowIndex) => {
272
- const params = { $table: $xeTable, $rowIndex, fixed: fixedType, type: renderType }
282
+ return cols.map((column, $columnIndex) => {
283
+ const { type, showHeaderOverflow, headerAlign, align, filters, editRender, cellRender, floatingFilters, filterRender, slots } = column
284
+ const colid = column.id
285
+ const colRest = fullColumnIdData[colid] || {}
286
+ const renderOpts = editRender || cellRender
287
+ const flSlot = slots ? (slots.floatingFilter || slots['floating-filter']) : null
288
+ const compConf = renderOpts ? renderer.get(renderOpts.name) : null
289
+ const flCompConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
290
+ const rtFloatingFilter = flCompConf ? flCompConf.renderTableFloatingFilter : null
291
+ const fixedHiddenColumn = overflowX && (fixedType ? column.fixed !== fixedType : !!column.fixed)
292
+ const isPadding = XEUtils.isBoolean(headerCellOpts.padding) ? headerCellOpts.padding : cellOpts.padding
293
+ const headOverflow = XEUtils.eqNull(showHeaderOverflow) ? allColumnHeaderOverflow : showHeaderOverflow
294
+ const headAlign = headerAlign || (compConf ? compConf.tableHeaderCellAlign : '') || allHeaderAlign || align || (compConf ? compConf.tableCellAlign : '') || allAlign
295
+ const showEllipsis = headOverflow === 'ellipsis'
296
+ const showTitle = headOverflow === 'title'
297
+ const showTooltip = headOverflow === true || headOverflow === 'tooltip'
298
+ const hasEllipsis = showTitle || showTooltip || showEllipsis
299
+ let hasFilter = false
300
+ let firstFilterOption: VxeTableDefines.FilterOption | null = null
301
+ if (filters) {
302
+ firstFilterOption = filters[0] as VxeTableDefines.FilterOption
303
+ hasFilter = filters.some((item) => item.checked)
304
+ }
305
+ const columnIndex = colRest.index
306
+ const _columnIndex = colRest._index
307
+ const cellParams: VxeTableDefines.CellFloatingFilterParams & {
308
+ $table: VxeTableConstructor & VxeTablePrivateMethods
309
+ } = {
310
+ $table: $xeTable,
311
+ $grid: $xeGrid,
312
+ $gantt: $xeGantt,
313
+ column,
314
+ columnIndex,
315
+ $columnIndex,
316
+ _columnIndex,
317
+ option: firstFilterOption,
318
+ fixed: fixedType,
319
+ type: renderType,
320
+ isHidden: fixedHiddenColumn,
321
+ hasFilter
322
+ }
323
+ const thAttrs: Record<string, string | number | null> = {
324
+ colid
325
+ }
326
+
327
+ const isLastColumn = $columnIndex === cols.length - 1
328
+ const isAutoCellWidth = !column.resizeWidth && (column.minWidth === 'auto' || column.width === 'auto')
329
+
330
+ const tcStyle: Record<string, string> = {}
331
+ if (hasEllipsis) {
332
+ tcStyle.height = `${currCellHeight}px`
333
+ } else {
334
+ tcStyle.minHeight = `${currCellHeight}px`
335
+ }
336
+
337
+ return h('th', {
338
+ class: ['vxe-table--column vxe-header--column', colid, fixedHiddenColumn ? 'fixed--hidden' : 'fixed--visible', {
339
+ [`col--${headAlign}`]: headAlign,
340
+ [`col--${type}`]: type,
341
+ 'col--last': isLastColumn,
342
+ 'col--fixed': column.fixed,
343
+ 'col--ellipsis': hasEllipsis,
344
+ 'fixed--width': !isAutoCellWidth,
345
+ 'is--padding': isPadding,
346
+ 'is--sortable': column.sortable,
347
+ 'col--current': currentColumn === column
348
+ }
349
+ ],
350
+ key: colid,
351
+ ...thAttrs
352
+ }, [
353
+ h('div', {
354
+ class: ['vxe-cell', {
355
+ 'c--title': showTitle,
356
+ 'c--tooltip': showTooltip,
357
+ 'c--ellipsis': showEllipsis
358
+ }],
359
+ style: tcStyle
360
+ }, isOptimizeMode && fixedHiddenColumn && !floatingFilters
361
+ ? []
362
+ : [
363
+ h('div', {
364
+ colid,
365
+ class: 'vxe-cell--wrapper vxe-header-cell--wrapper'
366
+ }, flSlot
367
+ ? $xeTable.callSlot(flSlot, cellParams)
368
+ : (rtFloatingFilter && firstFilterOption
369
+ ? getSlotVNs(rtFloatingFilter(filterRender, {
370
+ $table: $xeTable,
371
+ option: firstFilterOption,
372
+ column: column as any,
373
+ columnIndex,
374
+ $columnIndex
375
+ }))
376
+ : []))
377
+ ])
378
+ ])
379
+ })
380
+ }
381
+
382
+ const renderHeads = (isGroup: boolean, isOptimizeMode: boolean, headerGroups: VxeTableDefines.ColumnInfo[][]) => {
383
+ const { fixedType, fixedColumn } = props
273
384
 
385
+ const { headerRowClassName, headerRowStyle } = tableProps
386
+ const { visibleColumn } = tableInternalData
387
+ const floatingFilterOpts = computeFloatingFilterOpts.value
388
+ const rowVNs = headerGroups.map((cols, $rowIndex) => {
389
+ const params = { $table: $xeTable, $rowIndex, fixed: fixedType, type: renderType }
274
390
  return h('tr', {
275
391
  key: $rowIndex,
276
392
  class: [
@@ -280,6 +396,19 @@ export default defineVxeComponent({
280
396
  style: headerRowStyle ? (XEUtils.isFunction(headerRowStyle) ? headerRowStyle(params) : headerRowStyle) : null
281
397
  }, renderRows(isGroup, isOptimizeMode, headerGroups, $rowIndex, cols))
282
398
  })
399
+
400
+ if (floatingFilterOpts.enabled) {
401
+ rowVNs.push(
402
+ h('tr', {
403
+ key: 'ff',
404
+ class: [
405
+ 'vxe-header--row'
406
+ ]
407
+ }, renderFilterRows(isOptimizeMode, isOptimizeMode && fixedType ? fixedColumn as VxeTableDefines.ColumnInfo[] : visibleColumn))
408
+ )
409
+ }
410
+
411
+ return rowVNs
283
412
  }
284
413
 
285
414
  const renderVN = () => {
@@ -241,6 +241,8 @@ export const tableProps = {
241
241
  sortConfig: Object as PropType<VxeTablePropTypes.SortConfig>,
242
242
  // 筛选配置项
243
243
  filterConfig: Object as PropType<VxeTablePropTypes.FilterConfig>,
244
+ // 浮动筛选配置项
245
+ floatingFilterConfig: Object as PropType<VxeTablePropTypes.FloatingFilterConfig>,
244
246
  // 单选框配置
245
247
  radioConfig: Object as PropType<VxeTablePropTypes.RadioConfig>,
246
248
  // 复选框配置项
@@ -151,9 +151,7 @@ export default defineVxeComponent({
151
151
  isAllSelected: false,
152
152
  isIndeterminate: false,
153
153
  style: null,
154
- options: [],
155
154
  column: null,
156
- multiple: false,
157
155
  visible: false,
158
156
  maxHeight: null
159
157
  },
@@ -613,6 +611,10 @@ export default defineVxeComponent({
613
611
  return Object.assign({}, getConfig().table.filterConfig, props.filterConfig) as VxeTablePropTypes.FilterOpts
614
612
  })
615
613
 
614
+ const computeFloatingFilterOpts = computed(() => {
615
+ return Object.assign({}, getConfig().table.floatingFilterConfig, props.floatingFilterConfig)
616
+ })
617
+
616
618
  const computeMouseOpts = computed(() => {
617
619
  return Object.assign({}, getConfig().table.mouseConfig, props.mouseConfig) as VxeTablePropTypes.MouseOpts
618
620
  })
@@ -910,6 +912,7 @@ export default defineVxeComponent({
910
912
  computeEditOpts,
911
913
  computeSortOpts,
912
914
  computeFilterOpts,
915
+ computeFloatingFilterOpts,
913
916
  computeMouseOpts,
914
917
  computeAreaOpts,
915
918
  computeKeyboardOpts,
@@ -1785,7 +1788,7 @@ export default defineVxeComponent({
1785
1788
  fullColFieldData[field] = rest
1786
1789
  } else {
1787
1790
  if (storage && !type) {
1788
- errLog('vxe.error.reqSupportProp', ['storage', `${column.getTitle() || type || ''} -> field=?`])
1791
+ errLog('vxe.error.reqSupportProp', ['storage', `[${type ? `type=${type}` : `title=${column.getTitle()}`}]field=?`])
1789
1792
  }
1790
1793
  if (columnOpts.drag && (isCrossDrag || isSelfToChildDrag)) {
1791
1794
  errLog('vxe.error.reqSupportProp', ['column-drag-config.isCrossDrag | column-drag-config.isSelfToChildDrag', `${column.getTitle() || type || ''} -> field=?`])
@@ -6372,7 +6375,7 @@ export default defineVxeComponent({
6372
6375
  setFilterByEvent (evnt, fieldOrColumn, options) {
6373
6376
  const column = handleFieldOrColumn($xeTable, fieldOrColumn)
6374
6377
  if (column && column.filters) {
6375
- column.filters = toFilters(options || [])
6378
+ column.filters = toFilters(options || [], column.id)
6376
6379
  return $xeTable.handleColumnConfirmFilter(column, evnt)
6377
6380
  }
6378
6381
  return nextTick()
@@ -6386,13 +6389,13 @@ export default defineVxeComponent({
6386
6389
  const { column, visible } = filterStore
6387
6390
  filterStore.isAllSelected = false
6388
6391
  filterStore.isIndeterminate = false
6389
- filterStore.options = []
6390
6392
  filterStore.visible = false
6391
6393
  if (visible) {
6394
+ const field = column ? column.field : null
6392
6395
  dispatchEvent('filter-visible', {
6393
6396
  column,
6394
- property: column.field,
6395
- field: column.field,
6397
+ property: field,
6398
+ field,
6396
6399
  filterList: () => $xeTable.getCheckedFilters(),
6397
6400
  visible: false
6398
6401
  }, null)
@@ -7457,7 +7460,7 @@ export default defineVxeComponent({
7457
7460
  * 全局按下事件处理
7458
7461
  */
7459
7462
  const handleGlobalMousedownEvent = (evnt: MouseEvent) => {
7460
- const { editStore, ctxMenuStore, filterStore, customStore } = reactData
7463
+ const { editStore, ctxMenuStore, customStore } = reactData
7461
7464
  const { mouseConfig, editRules } = props
7462
7465
  const el = refElem.value
7463
7466
  const editOpts = computeEditOpts.value
@@ -7476,7 +7479,7 @@ export default defineVxeComponent({
7476
7479
  // 如果点击筛选容器
7477
7480
  } else {
7478
7481
  if (!getEventTargetNode(evnt, document.body, 'vxe-table--ignore-clear').flag) {
7479
- tablePrivateMethods.preventEvent(evnt, 'event.clearFilter', filterStore.args, tableMethods.closeFilter)
7482
+ tablePrivateMethods.preventEvent(evnt, 'event.clearFilter', internalData._currFilterParams, tableMethods.closeFilter)
7480
7483
  }
7481
7484
  }
7482
7485
  }
@@ -8972,24 +8975,25 @@ export default defineVxeComponent({
8972
8975
  reactData.reColumnFlag++
8973
8976
  },
8974
8977
  handleFilterOptions (column) {
8975
- const { filterStore } = reactData
8976
- const { filters, filterMultiple, filterRender } = column
8977
- const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
8978
- const frMethod = column.filterRecoverMethod || (compConf ? (compConf.tableFilterRecoverMethod || compConf.filterRecoverMethod) : null)
8979
- filterStore.multiple = filterMultiple
8980
- filterStore.options = filters
8981
- filterStore.column = column
8982
- // 复原状态
8983
- filterStore.options.forEach((option: any) => {
8984
- const { _checked, checked } = option
8985
- option._checked = checked
8986
- if (!checked && _checked !== checked) {
8987
- if (frMethod) {
8988
- frMethod({ option, column, $table: $xeTable })
8978
+ if (column) {
8979
+ const { filterStore } = reactData
8980
+ const { filterRender, filters } = column
8981
+ const filterOptions = filters || []
8982
+ const compConf = isEnableConf(filterRender) ? renderer.get(filterRender.name) : null
8983
+ const frMethod = column.filterRecoverMethod || (compConf ? (compConf.tableFilterRecoverMethod || compConf.filterRecoverMethod) : null)
8984
+ filterStore.column = column
8985
+ // 复原状态
8986
+ filterOptions.forEach((option: any) => {
8987
+ const { _checked, checked } = option
8988
+ option._checked = checked
8989
+ if (!checked && _checked !== checked) {
8990
+ if (frMethod) {
8991
+ frMethod({ option, column, $table: $xeTable })
8992
+ }
8989
8993
  }
8990
- }
8991
- })
8992
- $xeTable.checkFilterOptions()
8994
+ })
8995
+ $xeTable.checkFilterOptions()
8996
+ }
8993
8997
  },
8994
8998
  preventEvent (evnt, type, args, next, end) {
8995
8999
  let evntList = interceptor.get(type)
@@ -9962,8 +9966,8 @@ export default defineVxeComponent({
9962
9966
  $xeTable.handleHeaderCellDragMousedownEvent(evnt, params)
9963
9967
  }
9964
9968
  }
9965
- if (!triggerDrag && mouseConfig && mouseOpts.area && $xeTable.handleHeaderCellAreaModownEvent) {
9966
- $xeTable.handleHeaderCellAreaModownEvent(evnt, Object.assign({ cell, triggerSort, triggerFilter }, params))
9969
+ if (!triggerDrag && mouseConfig && mouseOpts.area && $xeTable.handleHeaderCellAreaMouseDnEvent) {
9970
+ $xeTable.handleHeaderCellAreaMouseDnEvent(evnt, Object.assign({ cell, triggerSort, triggerFilter }, params))
9967
9971
  }
9968
9972
  $xeTable.focus()
9969
9973
  if ($xeTable.closeMenu) {