stk-table-vue 0.2.5 → 0.2.7

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.
package/README.md CHANGED
@@ -40,7 +40,8 @@ repo:
40
40
  * [] 非虚拟滚动时,大数据分批加载。
41
41
  * [x] vue2.7支持(引入源码使用)。
42
42
  - [x] `props.optimizeVue2Scroll` 优化vue2虚拟滚动流畅度。
43
- * [] `props.emptyCellText` 支持传入函数。
43
+ * [x] `props.emptyCellText` 支持传入函数。
44
+ * [] 支持配置高亮参数。
44
45
 
45
46
 
46
47
  ## Usage
@@ -135,7 +136,7 @@ export type StkProps = {
135
136
  /** 列唯一键 */
136
137
  colKey?: UniqKeyProp;
137
138
  /** 空值展示文字 */
138
- emptyCellText?: string;
139
+ emptyCellText?: string | ((option: { row: DT; col: StkTableColumn<DT> }) => string);
139
140
  /** 暂无数据兜底高度是否撑满 */
140
141
  noDataFull?: boolean;
141
142
  /** 是否展示暂无数据 */
@@ -148,8 +149,6 @@ export type StkProps = {
148
149
  showOverflow?: boolean;
149
150
  /** 是否增加行hover class */
150
151
  showTrHoverClass?: boolean;
151
- /** 表头是否可拖动 */
152
- headerDrag?: boolean;
153
152
  /** 表头是否可拖动。支持回调函数。 */
154
153
  headerDrag?: boolean | ((col: StkTableColumn<DT>) => boolean);
155
154
  /**
@@ -348,6 +347,30 @@ export type StkTableColumn<T extends Record<string, any>> = {
348
347
  ```
349
348
 
350
349
 
350
+ ### StkTableColumn.SortConfig
351
+ ```ts
352
+ /** 排序配置 */
353
+ export type SortConfig<T extends Record<string, any>> = {
354
+ /** 空值始终排在列表末尾 */
355
+ emptyToBottom?: boolean;
356
+ /**
357
+ * 默认排序(1.初始化时触发 2.排序方向为null时触发)
358
+ * 类似onMounted时,调用setSorter点了下表头。
359
+ */
360
+ defaultSort?: {
361
+ dataIndex: keyof T;
362
+ order: Order;
363
+ /** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
364
+ silent?: boolean;
365
+ };
366
+ /**
367
+ * string排序是否使用 String.prototype.localCompare
368
+ * 默认true (&$&应该false)
369
+ */
370
+ stringLocaleCompare?: boolean;
371
+ };
372
+ ```
373
+
351
374
  ### Example
352
375
  ```vue
353
376
  <template>
@@ -420,3 +443,7 @@ export type StkTableColumn<T extends Record<string, any>> = {
420
443
  ### 鼠标悬浮表头时,不展示title
421
444
  * 将 `StkTableColumn` 中的 `title` 字段置为 "" 空字符串。这样th中就没有title了。
422
445
  * 使用 `StkTableColumn` 中的 `customHeaderCell` 属性中,自定义表头渲染。
446
+
447
+
448
+ ## Other
449
+ * `$*$` 兼容注释
@@ -16,9 +16,11 @@ declare function setCurrentRow(rowKey: string, option?: {
16
16
  * @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
17
17
  * @param option.sort 是否触发排序-默认true
18
18
  * @param option.silent 是否禁止触发回调-默认true
19
+ * @param option.force 是否触发排序-默认true
19
20
  */
20
21
  declare function setSorter(dataIndex: string, order: Order, option?: {
21
22
  sortOption?: SortOption<DT>;
23
+ force?: boolean;
22
24
  silent?: boolean;
23
25
  sort?: boolean;
24
26
  }): any[];
@@ -65,7 +67,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
65
67
  /** 列唯一键 */
66
68
  colKey?: UniqKeyProp | undefined;
67
69
  /** 空值展示文字 */
68
- emptyCellText?: string | undefined;
70
+ emptyCellText?: string | ((option: {
71
+ row: any;
72
+ col: StkTableColumn<any>;
73
+ }) => string) | undefined;
69
74
  /** 暂无数据兜底高度是否撑满 */
70
75
  noDataFull?: boolean | undefined;
71
76
  /** 是否展示暂无数据 */
@@ -163,7 +168,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
163
168
  /** 设置高亮渐暗单元格 */
164
169
  setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
165
170
  /** 设置高亮渐暗行 */
166
- setHighlightDimRow: (rowKeyValues: import("./types/index").UniqKey[]) => void;
171
+ setHighlightDimRow: (rowKeyValues: import("./types/index").UniqKey[], option?: {
172
+ useCss?: boolean | undefined;
173
+ }) => void;
167
174
  /** 表格排序列dataIndex */
168
175
  sortCol: import("vue").Ref<string | null | undefined>;
169
176
  /** 获取当前排序状态 */
@@ -225,7 +232,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
225
232
  /** 列唯一键 */
226
233
  colKey?: UniqKeyProp | undefined;
227
234
  /** 空值展示文字 */
228
- emptyCellText?: string | undefined;
235
+ emptyCellText?: string | ((option: {
236
+ row: any;
237
+ col: StkTableColumn<any>;
238
+ }) => string) | undefined;
229
239
  /** 暂无数据兜底高度是否撑满 */
230
240
  noDataFull?: boolean | undefined;
231
241
  /** 是否展示暂无数据 */
@@ -345,7 +355,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
345
355
  dataSource: any[];
346
356
  rowKey: UniqKeyProp;
347
357
  colKey: UniqKeyProp;
348
- emptyCellText: string;
358
+ emptyCellText: string | ((option: {
359
+ row: any;
360
+ col: StkTableColumn<any>;
361
+ }) => string);
349
362
  noDataFull: boolean;
350
363
  showNoData: boolean;
351
364
  sortRemote: boolean;
@@ -78,10 +78,15 @@ export type UniqKeyProp = UniqKey | UniqKeyFun;
78
78
  export type SortConfig<T extends Record<string, any>> = {
79
79
  /** 空值始终排在列表末尾 */
80
80
  emptyToBottom?: boolean;
81
- /** 默认排序(1.初始化时触发 2.排序方向为null时触发) */
81
+ /**
82
+ * 默认排序(1.初始化时触发 2.排序方向为null时触发)
83
+ * 类似onMounted时,调用setSorter点了下表头。
84
+ */
82
85
  defaultSort?: {
83
86
  dataIndex: keyof T;
84
87
  order: Order;
88
+ /** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
89
+ silent?: boolean;
85
90
  };
86
91
  /**
87
92
  * string排序是否使用 String.prototype.localCompare
@@ -89,4 +94,9 @@ export type SortConfig<T extends Record<string, any>> = {
89
94
  */
90
95
  stringLocaleCompare?: boolean;
91
96
  };
97
+ /** th td类型 */
98
+ export declare const enum TagType {
99
+ TH = 0,
100
+ TD = 1
101
+ }
92
102
  export {};
@@ -2,6 +2,7 @@ import { Ref } from 'vue';
2
2
  import { StkTableColumn } from './types';
3
3
  type Params<T extends Record<string, any>> = {
4
4
  props: any;
5
+ colKeyGen: (col: StkTableColumn<T>) => string;
5
6
  tableHeaderLast: Ref<StkTableColumn<T>[]>;
6
7
  tableContainer: Ref<HTMLDivElement | undefined>;
7
8
  };
@@ -9,9 +10,9 @@ type Params<T extends Record<string, any>> = {
9
10
  * 固定列处理
10
11
  * @returns
11
12
  */
12
- export declare function useFixedCol<DT extends Record<string, any>>({ props, tableHeaderLast, tableContainer }: Params<DT>): {
13
+ export declare function useFixedCol<DT extends Record<string, any>>({ props, colKeyGen, tableHeaderLast, tableContainer }: Params<DT>): {
13
14
  /** 固定列class */
14
- getFixedColClass: (col: StkTableColumn<DT>) => Record<string, boolean>;
15
+ fixedColClassMap: import("vue").ComputedRef<Map<any, any>>;
15
16
  /** 处理固定列阴影 */
16
17
  dealFixedColShadow: () => void;
17
18
  /** 滚动条变化时,更新需要展示阴影的列 */
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, Ref } from 'vue';
2
- import { StkTableColumn } from './types';
2
+ import { StkTableColumn, TagType } from './types';
3
3
  import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
4
4
  type Options<T extends Record<string, any>> = {
5
5
  props: any;
@@ -15,6 +15,6 @@ type Options<T extends Record<string, any>> = {
15
15
  * @returns
16
16
  */
17
17
  export declare function useFixedStyle<DT extends Record<string, any>>({ props, tableHeaders, virtualScroll, virtualScrollX, virtualX_on, virtualX_offsetRight, }: Options<DT>): {
18
- getFixedStyle: (tagType: 1 | 2, col: StkTableColumn<any>, depth?: number) => CSSProperties;
18
+ getFixedStyle: (tagType: TagType, col: StkTableColumn<DT>, depth?: number) => CSSProperties;
19
19
  };
20
20
  export {};
@@ -20,7 +20,9 @@ type HighlightRowStore = {
20
20
  */
21
21
  export declare function useHighlight({ props, tableContainer }: Params): {
22
22
  highlightRowStore: Ref<Record<UniqKey, HighlightRowStore>>;
23
- setHighlightDimRow: (rowKeyValues: UniqKey[]) => void;
23
+ setHighlightDimRow: (rowKeyValues: UniqKey[], option?: {
24
+ useCss?: boolean;
25
+ }) => void;
24
26
  setHighlightDimCell: (rowKeyValue: string, dataIndex: string) => void;
25
27
  };
26
28
  export {};
@@ -1,4 +1,4 @@
1
- import { onMounted, onBeforeUnmount, watch, ref, computed, defineComponent, shallowRef, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withDirectives, createElementVNode, vShow, Fragment, renderList, createCommentVNode, createBlock, resolveDynamicComponent, renderSlot, toDisplayString, createTextVNode } from "vue";
1
+ import { onMounted, onBeforeUnmount, watch, ref, shallowRef, computed, defineComponent, toRaw, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withDirectives, createElementVNode, vShow, Fragment, renderList, createCommentVNode, createBlock, resolveDynamicComponent, renderSlot, toDisplayString, createTextVNode } from "vue";
2
2
  import { interpolateRgb } from "d3-interpolate";
3
3
  const Default_Col_Width = "100";
4
4
  const Default_Table_Height = 100;
@@ -20,6 +20,11 @@ try {
20
20
  console.error("Cannot get Chrome version", e);
21
21
  }
22
22
  const Is_Legacy_Mode = _chromeVersion < 56;
23
+ var TagType = /* @__PURE__ */ ((TagType2) => {
24
+ TagType2[TagType2["TH"] = 0] = "TH";
25
+ TagType2[TagType2["TD"] = 1] = "TD";
26
+ return TagType2;
27
+ })(TagType || {});
23
28
  function useAutoResize({ tableContainer, initVirtualScroll, props, debounceMs }) {
24
29
  let resizeObserver = null;
25
30
  onMounted(() => {
@@ -325,16 +330,30 @@ function useColResize({
325
330
  onThResizeMouseUp
326
331
  };
327
332
  }
328
- function useFixedCol({ props, tableHeaderLast, tableContainer }) {
333
+ function useFixedCol({ props, colKeyGen, tableHeaderLast, tableContainer }) {
329
334
  const fixedShadow = ref({
330
335
  showL: false,
331
336
  showR: false
332
337
  });
333
- let fixedShadowCols = [];
338
+ const fixedShadowCols = shallowRef([]);
339
+ const fixedColClassMap = computed(() => {
340
+ const colMap = /* @__PURE__ */ new Map();
341
+ props.columns.forEach((col) => {
342
+ const { showR, showL } = fixedShadow.value;
343
+ const showShadow = props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && fixedShadowCols.value.includes(col);
344
+ const classObj = {
345
+ "fixed-cell": col.fixed,
346
+ ["fixed-cell--" + col.fixed]: col.fixed,
347
+ "fixed-cell--shadow": showShadow
348
+ };
349
+ colMap.set(colKeyGen(col), classObj);
350
+ });
351
+ return colMap;
352
+ });
334
353
  function dealFixedColShadow() {
335
354
  if (!props.fixedColShadow)
336
355
  return;
337
- fixedShadowCols = [];
356
+ fixedShadowCols.value = [];
338
357
  let lastLeftCol = null;
339
358
  for (let i = tableHeaderLast.value.length - 1; i >= 0; i--) {
340
359
  const col = tableHeaderLast.value[i];
@@ -346,27 +365,17 @@ function useFixedCol({ props, tableHeaderLast, tableContainer }) {
346
365
  let node = { __PARENT__: lastLeftCol };
347
366
  while (node = node.__PARENT__) {
348
367
  if (node.fixed) {
349
- fixedShadowCols.push(node);
368
+ fixedShadowCols.value.push(node);
350
369
  }
351
370
  }
352
371
  const lastRightCol = tableHeaderLast.value.find((it) => it.fixed === "right");
353
372
  node = { __PARENT__: lastRightCol };
354
373
  while (node = node.__PARENT__) {
355
374
  if (node.fixed) {
356
- fixedShadowCols.push(node);
375
+ fixedShadowCols.value.push(node);
357
376
  }
358
377
  }
359
378
  }
360
- function getFixedColClass(col) {
361
- const { showR, showL } = fixedShadow.value;
362
- const showShadow = props.fixedColShadow && col.fixed && (showL && col.fixed === "left" || showR && col.fixed === "right") && fixedShadowCols.includes(col);
363
- const classObj = {
364
- "fixed-cell": col.fixed,
365
- ["fixed-cell--" + col.fixed]: col.fixed,
366
- "fixed-cell--shadow": showShadow
367
- };
368
- return classObj;
369
- }
370
379
  function updateFixedShadow() {
371
380
  if (!props.fixedColShadow)
372
381
  return;
@@ -376,7 +385,7 @@ function useFixedCol({ props, tableHeaderLast, tableContainer }) {
376
385
  }
377
386
  return {
378
387
  /** 固定列class */
379
- getFixedColClass,
388
+ fixedColClassMap,
380
389
  /** 处理固定列阴影 */
381
390
  dealFixedColShadow,
382
391
  /** 滚动条变化时,更新需要展示阴影的列 */
@@ -436,7 +445,7 @@ function useFixedStyle({
436
445
  } else {
437
446
  style.position = "sticky";
438
447
  }
439
- if (tagType === 1) {
448
+ if (tagType === TagType.TH) {
440
449
  if (Is_Legacy_Mode) {
441
450
  style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + "px";
442
451
  } else {
@@ -499,6 +508,7 @@ function useHighlight({ props, tableContainer }) {
499
508
  highlightDimRowKeys.delete(rowKeyValue);
500
509
  }
501
510
  });
511
+ highlightRowStore.value = { ...highlightRowStore.value };
502
512
  if (highlightDimRowKeys.size > 0) {
503
513
  recursion();
504
514
  } else {
@@ -527,16 +537,16 @@ function useHighlight({ props, tableContainer }) {
527
537
  }, Highlight_Duration)
528
538
  );
529
539
  }
530
- function setHighlightDimRow(rowKeyValues) {
540
+ function setHighlightDimRow(rowKeyValues, option = {}) {
531
541
  var _a, _b;
532
542
  if (!Array.isArray(rowKeyValues))
533
543
  rowKeyValues = [rowKeyValues];
534
- if (props.virtual) {
544
+ if (props.virtual && !option.useCss) {
535
545
  const nowTs = Date.now();
536
546
  for (let i = 0; i < rowKeyValues.length; i++) {
537
547
  const rowKeyValue = rowKeyValues[i];
538
548
  highlightRowStore.value[rowKeyValue] = {
539
- bgc: "",
549
+ bgc: highlightFrom.value,
540
550
  bgc_progress: 0,
541
551
  bgc_progress_ms: nowTs
542
552
  };
@@ -954,7 +964,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
954
964
  dataSource: { default: () => [] },
955
965
  rowKey: { type: [String, Number, Function], default: "" },
956
966
  colKey: { type: [String, Number, Function], default: "dataIndex" },
957
- emptyCellText: { default: "--" },
967
+ emptyCellText: { type: [String, Function], default: "--" },
958
968
  noDataFull: { type: Boolean, default: false },
959
969
  showNoData: { type: Boolean, default: true },
960
970
  sortRemote: { type: Boolean, default: false },
@@ -990,6 +1000,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
990
1000
  const tableHeaders = ref([]);
991
1001
  const tableHeaderLast = ref([]);
992
1002
  const dataSourceCopy = shallowRef([...props.dataSource]);
1003
+ const getEmptyCellText = computed(() => {
1004
+ if (typeof props.emptyCellText === "string") {
1005
+ return () => props.emptyCellText;
1006
+ } else {
1007
+ return (col, row) => props.emptyCellText({ row, col });
1008
+ }
1009
+ });
993
1010
  const rowKeyGenStore = /* @__PURE__ */ new WeakMap();
994
1011
  const { isColResizing, onThResizeMouseDown } = useColResize({
995
1012
  props,
@@ -1034,8 +1051,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1034
1051
  virtualScrollX,
1035
1052
  tableHeaders
1036
1053
  });
1037
- const { getFixedColClass, dealFixedColShadow, updateFixedShadow } = useFixedCol({
1054
+ const { fixedColClassMap, dealFixedColShadow, updateFixedShadow } = useFixedCol({
1038
1055
  props,
1056
+ colKeyGen,
1039
1057
  tableContainer,
1040
1058
  tableHeaderLast
1041
1059
  });
@@ -1080,8 +1098,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1080
1098
  function dealDefaultSorter() {
1081
1099
  if (!props.sortConfig.defaultSort)
1082
1100
  return;
1083
- const { dataIndex, order } = props.sortConfig.defaultSort;
1084
- setSorter(dataIndex, order);
1101
+ const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
1102
+ setSorter(dataIndex, order, { force: false, silent });
1085
1103
  }
1086
1104
  function dealColumns() {
1087
1105
  tableHeaders.value = [];
@@ -1149,33 +1167,42 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1149
1167
  function colKeyGen(col) {
1150
1168
  return typeof props.colKey === "function" ? props.colKey(col) : col[props.colKey];
1151
1169
  }
1152
- function getColWidthStyle(col) {
1153
- const width = getColWidthStr(col);
1154
- const minWidth = getColWidthStr(col, "minWidth");
1155
- const maxWidth = getColWidthStr(col, "maxWidth");
1156
- const style = {
1157
- width,
1158
- minWidth: minWidth ?? width,
1159
- maxWidth: maxWidth ?? width
1160
- };
1161
- if (props.colResizable) {
1162
- style.minWidth = width;
1163
- style.maxWidth = width;
1164
- }
1165
- return style;
1166
- }
1167
- function getCellStyle(tagType, col, depth) {
1168
- const style = {
1169
- ...getColWidthStyle(col),
1170
- ...getFixedStyle(tagType, col, depth)
1170
+ const cellStyleMap = computed(() => {
1171
+ const thMap = /* @__PURE__ */ new Map();
1172
+ const tdMap = /* @__PURE__ */ new Map();
1173
+ tableHeaders.value.forEach((cols, depth) => {
1174
+ cols.forEach((col) => {
1175
+ const colKey = colKeyGen(col);
1176
+ const width = getColWidthStr(col);
1177
+ const style = {
1178
+ width
1179
+ };
1180
+ if (props.colResizable) {
1181
+ style.minWidth = width;
1182
+ style.maxWidth = width;
1183
+ } else {
1184
+ style.minWidth = getColWidthStr(col, "minWidth") ?? width;
1185
+ style.maxWidth = getColWidthStr(col, "maxWidth") ?? width;
1186
+ }
1187
+ const thStyle = {
1188
+ ...style,
1189
+ ...getFixedStyle(TagType.TH, col, depth),
1190
+ textAlign: col.headerAlign
1191
+ };
1192
+ const tdStyle = {
1193
+ ...style,
1194
+ ...getFixedStyle(TagType.TD, col, depth),
1195
+ textAlign: col.align
1196
+ };
1197
+ thMap.set(colKey, thStyle);
1198
+ tdMap.set(colKey, tdStyle);
1199
+ });
1200
+ });
1201
+ return {
1202
+ [TagType.TH]: thMap,
1203
+ [TagType.TD]: tdMap
1171
1204
  };
1172
- if (tagType === 1) {
1173
- style.textAlign = col.headerAlign;
1174
- } else if (tagType === 2) {
1175
- style.textAlign = col.align;
1176
- }
1177
- return style;
1178
- }
1205
+ });
1179
1206
  function getHeaderTitle(col) {
1180
1207
  if (props.hideHeaderTitle === true || Array.isArray(props.hideHeaderTitle) && props.hideHeaderTitle.includes(col.dataIndex)) {
1181
1208
  return "";
@@ -1288,7 +1315,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1288
1315
  if (newOption.sort && ((_a = dataSourceCopy.value) == null ? void 0 : _a.length)) {
1289
1316
  const column = newOption.sortOption || tableHeaderLast.value.find((it) => it.dataIndex === sortCol.value);
1290
1317
  if (column)
1291
- onColumnSort(column, false, { force: true, emit: !newOption.silent });
1318
+ onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
1292
1319
  else
1293
1320
  console.warn("Can not find column by dataIndex:", sortCol.value);
1294
1321
  }
@@ -1402,14 +1429,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1402
1429
  draggable: unref(isHeaderDraggable)(col) ? "true" : "false",
1403
1430
  rowspan: unref(virtualX_on) ? 1 : col.rowSpan,
1404
1431
  colspan: col.colSpan,
1405
- style: normalizeStyle(getCellStyle(1, col, rowIndex)),
1432
+ style: normalizeStyle(cellStyleMap.value[unref(TagType).TH].get(colKeyGen(col))),
1406
1433
  title: getHeaderTitle(col),
1407
1434
  class: normalizeClass([
1408
1435
  col.sorter ? "sortable" : "",
1409
1436
  col.dataIndex === unref(sortCol) && unref(sortOrderIndex) !== 0 && "sorter-" + sortSwitchOrder[unref(sortOrderIndex)],
1410
1437
  _ctx.showHeaderOverflow ? "text-overflow" : "",
1411
1438
  col.headerClassName,
1412
- unref(getFixedColClass)(col)
1439
+ unref(fixedColClassMap).get(colKeyGen(col))
1413
1440
  ]),
1414
1441
  onClick: (e) => {
1415
1442
  onColumnSort(col);
@@ -1467,7 +1494,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1467
1494
  _ctx.fixedMode && _ctx.headless ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(virtualX_columnPart), (col) => {
1468
1495
  return openBlock(), createElementBlock("td", {
1469
1496
  key: col.dataIndex,
1470
- style: normalizeStyle(getCellStyle(2, col))
1497
+ style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen(col)))
1471
1498
  }, null, 4);
1472
1499
  }), 128)) : createCommentVNode("", true)
1473
1500
  ], 4)) : createCommentVNode("", true),
@@ -1494,8 +1521,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1494
1521
  return openBlock(), createElementBlock("td", {
1495
1522
  key: col.dataIndex,
1496
1523
  "data-index": col.dataIndex,
1497
- class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", unref(getFixedColClass)(col)]),
1498
- style: normalizeStyle(getCellStyle(2, col)),
1524
+ class: normalizeClass([col.className, _ctx.showOverflow ? "text-overflow" : "", unref(fixedColClassMap).get(colKeyGen(col))]),
1525
+ style: normalizeStyle(cellStyleMap.value[unref(TagType).TD].get(colKeyGen(col))),
1499
1526
  onClick: (e) => onCellClick(e, row, col)
1500
1527
  }, [
1501
1528
  col.customCell ? (openBlock(), createBlock(resolveDynamicComponent(col.customCell), {
@@ -1507,7 +1534,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1507
1534
  key: 1,
1508
1535
  class: "table-cell-wrapper",
1509
1536
  title: row[col.dataIndex]
1510
- }, toDisplayString(row[col.dataIndex] ?? _ctx.emptyCellText), 9, _hoisted_14))
1537
+ }, toDisplayString(row[col.dataIndex] ?? getEmptyCellText.value(col, row)), 9, _hoisted_14))
1511
1538
  ], 14, _hoisted_13);
1512
1539
  }), 128))
1513
1540
  ], 46, _hoisted_11);
package/package.json CHANGED
@@ -1,61 +1,61 @@
1
- {
2
- "name": "stk-table-vue",
3
- "version": "0.2.5",
4
- "description": "Simple realtime virtual table for vue3&vue2.7",
5
- "main": "./lib/stk-table-vue.js",
6
- "types": "./lib/StkTable/index.d.ts",
7
- "packageManager": "pnpm@8.14.3",
8
- "directories": {
9
- "test": "test"
10
- },
11
- "type": "module",
12
- "scripts": {
13
- "dev": "vite",
14
- "build": "vite build",
15
- "test": "vitest"
16
- },
17
- "keywords": [
18
- "virtual table",
19
- "vue",
20
- "highlight",
21
- "sticky"
22
- ],
23
- "files": [
24
- "lib",
25
- "src"
26
- ],
27
- "author": "japlus",
28
- "repository": {
29
- "type": "git",
30
- "url": "https://gitee.com/japlus/stk-table-vue"
31
- },
32
- "license": "MIT",
33
- "devDependencies": {
34
- "@types/d3-interpolate": "^3.0.4",
35
- "@types/node": "^20.11.14",
36
- "@typescript-eslint/eslint-plugin": "^6.14.0",
37
- "@typescript-eslint/parser": "^6.14.0",
38
- "@vitejs/plugin-vue": "^5.0.3",
39
- "@vitejs/plugin-vue-jsx": "^3.1.0",
40
- "@vue/test-utils": "2.4.4",
41
- "eslint": "^8.55.0",
42
- "eslint-config-prettier": "^9.1.0",
43
- "eslint-plugin-html": "^7.1.0",
44
- "eslint-plugin-prettier": "^5.0.1",
45
- "eslint-plugin-vue": "^9.19.2",
46
- "happy-dom": "^12.10.3",
47
- "less": "^4.2.0",
48
- "postcss-discard-comments": "^6.0.1",
49
- "postcss-preset-env": "^9.3.0",
50
- "prettier": "^3.1.1",
51
- "typescript": "^5.3.3",
52
- "vite": "^5.1.4",
53
- "vite-plugin-dts": "^3.7.3",
54
- "vitest": "^1.1.0",
55
- "vue": "^3.4.19",
56
- "vue-eslint-parser": "^9.3.2"
57
- },
58
- "dependencies": {
59
- "d3-interpolate": "^3.0.1"
60
- }
1
+ {
2
+ "name": "stk-table-vue",
3
+ "version": "0.2.7",
4
+ "description": "Simple realtime virtual table for vue3&vue2.7",
5
+ "main": "./lib/stk-table-vue.js",
6
+ "types": "./lib/src/StkTable/index.d.ts",
7
+ "packageManager": "pnpm@8.14.3",
8
+ "directories": {
9
+ "test": "test"
10
+ },
11
+ "type": "module",
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "vite build",
15
+ "test": "vitest"
16
+ },
17
+ "keywords": [
18
+ "virtual table",
19
+ "vue",
20
+ "highlight",
21
+ "sticky"
22
+ ],
23
+ "files": [
24
+ "lib",
25
+ "src"
26
+ ],
27
+ "author": "japlus",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://gitee.com/japlus/stk-table-vue"
31
+ },
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "@types/d3-interpolate": "^3.0.4",
35
+ "@types/node": "^20.11.14",
36
+ "@typescript-eslint/eslint-plugin": "^6.14.0",
37
+ "@typescript-eslint/parser": "^6.14.0",
38
+ "@vitejs/plugin-vue": "^5.0.3",
39
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
40
+ "@vue/test-utils": "2.4.4",
41
+ "eslint": "^8.55.0",
42
+ "eslint-config-prettier": "^9.1.0",
43
+ "eslint-plugin-html": "^7.1.0",
44
+ "eslint-plugin-prettier": "^5.0.1",
45
+ "eslint-plugin-vue": "^9.19.2",
46
+ "happy-dom": "^12.10.3",
47
+ "less": "^4.2.0",
48
+ "postcss-discard-comments": "^6.0.1",
49
+ "postcss-preset-env": "^9.3.0",
50
+ "prettier": "^3.1.1",
51
+ "typescript": "^5.3.3",
52
+ "vite": "^5.1.4",
53
+ "vite-plugin-dts": "^3.7.3",
54
+ "vitest": "^1.1.0",
55
+ "vue": "^3.4.19",
56
+ "vue-eslint-parser": "^9.3.2"
57
+ },
58
+ "dependencies": {
59
+ "d3-interpolate": "^3.0.1"
60
+ }
61
61
  }
@@ -60,14 +60,14 @@
60
60
  :draggable="isHeaderDraggable(col) ? 'true' : 'false'"
61
61
  :rowspan="virtualX_on ? 1 : col.rowSpan"
62
62
  :colspan="col.colSpan"
63
- :style="getCellStyle(1, col, rowIndex)"
63
+ :style="cellStyleMap[TagType.TH].get(colKeyGen(col))"
64
64
  :title="getHeaderTitle(col)"
65
65
  :class="[
66
66
  col.sorter ? 'sortable' : '',
67
67
  col.dataIndex === sortCol && sortOrderIndex !== 0 && 'sorter-' + sortSwitchOrder[sortOrderIndex],
68
68
  showHeaderOverflow ? 'text-overflow' : '',
69
69
  col.headerClassName,
70
- getFixedColClass(col),
70
+ fixedColClassMap.get(colKeyGen(col)),
71
71
  ]"
72
72
  @click="
73
73
  e => {
@@ -135,7 +135,7 @@
135
135
  <!--这个td用于配合虚拟滚动的th对应,防止列错位-->
136
136
  <td v-if="virtualX_on && fixedMode && headless" class="virtual-x-left" style="padding: 0"></td>
137
137
  <template v-if="fixedMode && headless">
138
- <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="getCellStyle(2, col)"></td
138
+ <td v-for="col in virtualX_columnPart" :key="col.dataIndex" :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"></td
139
139
  ></template>
140
140
  </tr>
141
141
  <tr
@@ -161,13 +161,13 @@
161
161
  v-for="col in virtualX_columnPart"
162
162
  :key="col.dataIndex"
163
163
  :data-index="col.dataIndex"
164
- :class="[col.className, showOverflow ? 'text-overflow' : '', getFixedColClass(col)]"
165
- :style="getCellStyle(2, col)"
164
+ :class="[col.className, showOverflow ? 'text-overflow' : '', fixedColClassMap.get(colKeyGen(col))]"
165
+ :style="cellStyleMap[TagType.TD].get(colKeyGen(col))"
166
166
  @click="e => onCellClick(e, row, col)"
167
167
  >
168
168
  <component :is="col.customCell" v-if="col.customCell" :col="col" :row="row" :cell-value="row[col.dataIndex]" />
169
169
  <div v-else class="table-cell-wrapper" :title="row[col.dataIndex]">
170
- {{ row[col.dataIndex] ?? emptyCellText }}
170
+ {{ row[col.dataIndex] ?? getEmptyCellText(col, row) }}
171
171
  </div>
172
172
  </td>
173
173
  </tr>
@@ -189,9 +189,9 @@
189
189
  * [] 计算的高亮颜色,挂在数据源上对象上,若多个表格使用同一个数据源对象会有问题。需要深拷贝。(解决方案:获取组件uid)
190
190
  * [] highlight-row 颜色不能恢复到active的颜色
191
191
  */
192
- import { CSSProperties, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
192
+ import { CSSProperties, computed, onMounted, ref, shallowRef, toRaw, watch } from 'vue';
193
193
  import { Default_Row_Height } from './const';
194
- import { Order, SortConfig, SortOption, SortState, StkTableColumn, UniqKeyProp } from './types/index';
194
+ import { Order, SortConfig, SortOption, SortState, StkTableColumn, TagType, UniqKeyProp } from './types/index';
195
195
  import { useAutoResize } from './useAutoResize';
196
196
  import { useColResize } from './useColResize';
197
197
  import { useFixedCol } from './useFixedCol';
@@ -239,7 +239,7 @@ const props = withDefaults(
239
239
  /** 列唯一键 */
240
240
  colKey?: UniqKeyProp;
241
241
  /** 空值展示文字 */
242
- emptyCellText?: string; //TODO: 支持传入方法
242
+ emptyCellText?: string | ((option: { row: DT; col: StkTableColumn<DT> }) => string);
243
243
  /** 暂无数据兜底高度是否撑满 */
244
244
  noDataFull?: boolean;
245
245
  /** 是否展示暂无数据 */
@@ -258,7 +258,7 @@ const props = withDefaults(
258
258
  * 给行附加className<br>
259
259
  * FIXME: 是否需要优化,因为不传此prop会使表格行一直执行空函数,是否有影响
260
260
  */
261
- rowClassName?: (row: any, i: number) => string;
261
+ rowClassName?: (row: DT, i: number) => string;
262
262
  /**
263
263
  * 列宽是否可拖动<br>
264
264
  * **不要设置**列minWidth,**必须**设置width<br>
@@ -446,6 +446,15 @@ const dataSourceCopy = shallowRef<DT[]>([...props.dataSource]);
446
446
  /**高亮帧间隔
447
447
  const highlightStepDuration = Highlight_Color_Change_Freq / 1000 + 's';*/
448
448
 
449
+ /** 空单元格占位字符 */
450
+ const getEmptyCellText = computed(() => {
451
+ if (typeof props.emptyCellText === 'string') {
452
+ return () => props.emptyCellText;
453
+ } else {
454
+ return (col: StkTableColumn<DT>, row: DT) => (props.emptyCellText as any)({ row, col });
455
+ }
456
+ });
457
+
449
458
  /** rowKey缓存 */
450
459
  const rowKeyGenStore = new WeakMap();
451
460
 
@@ -504,8 +513,9 @@ useKeyboardArrowScroll(tableContainer, {
504
513
  });
505
514
 
506
515
  /** 固定列处理 */
507
- const { getFixedColClass, dealFixedColShadow, updateFixedShadow } = useFixedCol({
516
+ const { fixedColClassMap, dealFixedColShadow, updateFixedShadow } = useFixedCol({
508
517
  props,
518
+ colKeyGen,
509
519
  tableContainer,
510
520
  tableHeaderLast,
511
521
  });
@@ -558,8 +568,8 @@ onMounted(() => {
558
568
  /** 处理默认排序 */
559
569
  function dealDefaultSorter() {
560
570
  if (!props.sortConfig.defaultSort) return;
561
- const { dataIndex, order } = props.sortConfig.defaultSort;
562
- setSorter(dataIndex as string, order);
571
+ const { dataIndex, order, silent } = { silent: false, ...props.sortConfig.defaultSort };
572
+ setSorter(dataIndex as string, order, { force: false, silent });
563
573
  }
564
574
 
565
575
  /**
@@ -659,47 +669,45 @@ function colKeyGen(col: StkTableColumn<DT>) {
659
669
  return typeof props.colKey === 'function' ? props.colKey(col) : (col as any)[props.colKey];
660
670
  }
661
671
 
662
- /** 获取列宽度样式 */
663
- function getColWidthStyle(col: StkTableColumn<DT>) {
664
- const width = getColWidthStr(col);
665
- const minWidth = getColWidthStr(col, 'minWidth');
666
- const maxWidth = getColWidthStr(col, 'maxWidth');
667
- const style: CSSProperties = {
668
- width,
669
- minWidth: minWidth ?? width,
670
- maxWidth: maxWidth ?? width,
671
- };
672
- if (props.colResizable) {
673
- style.minWidth = width;
674
- style.maxWidth = width;
675
- }
676
-
677
- return style;
678
- }
672
+ /** 单元格样式 */
673
+ const cellStyleMap = computed(() => {
674
+ const thMap = new Map();
675
+ const tdMap = new Map();
676
+ tableHeaders.value.forEach((cols, depth) => {
677
+ cols.forEach(col => {
678
+ const colKey = colKeyGen(col);
679
+ const width = getColWidthStr(col);
680
+ const style: CSSProperties = {
681
+ width,
682
+ };
683
+ if (props.colResizable) {
684
+ style.minWidth = width;
685
+ style.maxWidth = width;
686
+ } else {
687
+ style.minWidth = getColWidthStr(col, 'minWidth') ?? width;
688
+ style.maxWidth = getColWidthStr(col, 'maxWidth') ?? width;
689
+ }
679
690
 
680
- /**
681
- * 性能优化,缓存style行内样式
682
- *
683
- * FIXME: col变化时仍从缓存拿style。watch col?
684
- * @param tagType 1-th 2-td
685
- * @param col
686
- * @param depth 表头层级
687
- */
688
- function getCellStyle(tagType: 1 | 2, col: StkTableColumn<DT>, depth?: number): CSSProperties {
689
- const style: CSSProperties = {
690
- ...getColWidthStyle(col),
691
- ...getFixedStyle(tagType, col, depth),
691
+ const thStyle = {
692
+ ...style,
693
+ ...getFixedStyle(TagType.TH, col, depth),
694
+ textAlign: col.headerAlign,
695
+ };
696
+ const tdStyle = {
697
+ ...style,
698
+ ...getFixedStyle(TagType.TD, col, depth),
699
+ textAlign: col.align,
700
+ };
701
+
702
+ thMap.set(colKey, thStyle);
703
+ tdMap.set(colKey, tdStyle);
704
+ });
705
+ });
706
+ return {
707
+ [TagType.TH]: thMap,
708
+ [TagType.TD]: tdMap,
692
709
  };
693
- if (tagType === 1) {
694
- // TH
695
- style.textAlign = col.headerAlign;
696
- } else if (tagType === 2) {
697
- // TD
698
- style.textAlign = col.align;
699
- }
700
-
701
- return style;
702
- }
710
+ });
703
711
 
704
712
  /** th title */
705
713
  function getHeaderTitle(col: StkTableColumn<DT>): string {
@@ -859,8 +867,9 @@ function setCurrentRow(rowKey: string, option = { silent: false }) {
859
867
  * @param option.sortOption 指定排序参数。同 StkTableColumn 中排序相关字段。建议从columns中find得到。
860
868
  * @param option.sort 是否触发排序-默认true
861
869
  * @param option.silent 是否禁止触发回调-默认true
870
+ * @param option.force 是否触发排序-默认true
862
871
  */
863
- function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; silent?: boolean; sort?: boolean } = {}) {
872
+ function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortOption<DT>; force?: boolean; silent?: boolean; sort?: boolean } = {}) {
864
873
  const newOption = { silent: true, sortOption: null, sort: true, ...option };
865
874
  sortCol.value = dataIndex;
866
875
  sortOrderIndex.value = sortSwitchOrder.indexOf(order);
@@ -868,7 +877,7 @@ function setSorter(dataIndex: string, order: Order, option: { sortOption?: SortO
868
877
  if (newOption.sort && dataSourceCopy.value?.length) {
869
878
  // 如果表格有数据,则进行排序
870
879
  const column = newOption.sortOption || tableHeaderLast.value.find(it => it.dataIndex === sortCol.value);
871
- if (column) onColumnSort(column, false, { force: true, emit: !newOption.silent });
880
+ if (column) onColumnSort(column, false, { force: option.force ?? true, emit: !newOption.silent });
872
881
  else console.warn('Can not find column by dataIndex:', sortCol.value);
873
882
  }
874
883
  return dataSourceCopy.value;
@@ -77,10 +77,15 @@ export type UniqKeyProp = UniqKey | UniqKeyFun;
77
77
  export type SortConfig<T extends Record<string, any>> = {
78
78
  /** 空值始终排在列表末尾 */
79
79
  emptyToBottom?: boolean;
80
- /** 默认排序(1.初始化时触发 2.排序方向为null时触发) */
80
+ /**
81
+ * 默认排序(1.初始化时触发 2.排序方向为null时触发)
82
+ * 类似onMounted时,调用setSorter点了下表头。
83
+ */
81
84
  defaultSort?: {
82
85
  dataIndex: keyof T;
83
86
  order: Order;
87
+ /** 是否禁止触发sort-change事件。默认false,表示触发事件。 */
88
+ silent?: boolean;
84
89
  };
85
90
  /**
86
91
  * string排序是否使用 String.prototype.localCompare
@@ -88,3 +93,9 @@ export type SortConfig<T extends Record<string, any>> = {
88
93
  */
89
94
  stringLocaleCompare?: boolean;
90
95
  };
96
+
97
+ /** th td类型 */
98
+ export const enum TagType {
99
+ TH,
100
+ TD,
101
+ }
@@ -1,8 +1,9 @@
1
- import { ref, Ref } from 'vue';
1
+ import { computed, ref, Ref, shallowRef } from 'vue';
2
2
  import { StkTableColumn } from './types';
3
3
 
4
4
  type Params<T extends Record<string, any>> = {
5
5
  props: any;
6
+ colKeyGen: (col: StkTableColumn<T>) => string;
6
7
  tableHeaderLast: Ref<StkTableColumn<T>[]>;
7
8
  tableContainer: Ref<HTMLDivElement | undefined>;
8
9
  };
@@ -11,7 +12,7 @@ type Params<T extends Record<string, any>> = {
11
12
  * 固定列处理
12
13
  * @returns
13
14
  */
14
- export function useFixedCol<DT extends Record<string, any>>({ props, tableHeaderLast, tableContainer }: Params<DT>) {
15
+ export function useFixedCol<DT extends Record<string, any>>({ props, colKeyGen, tableHeaderLast, tableContainer }: Params<DT>) {
15
16
  /** 固定列阴影 */
16
17
  const fixedShadow = ref<{
17
18
  /** 是否展示左侧固定列阴影 */
@@ -23,12 +24,31 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
23
24
  showR: false,
24
25
  });
25
26
  /** 保存需要出现阴影的列 */
26
- let fixedShadowCols: StkTableColumn<DT>[] = [];
27
+ const fixedShadowCols = shallowRef<StkTableColumn<DT>[]>([]);
28
+
29
+ const fixedColClassMap = computed(() => {
30
+ const colMap = new Map();
31
+ props.columns.forEach((col: any) => {
32
+ const { showR, showL } = fixedShadow.value;
33
+ const showShadow =
34
+ props.fixedColShadow &&
35
+ col.fixed &&
36
+ ((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) &&
37
+ fixedShadowCols.value.includes(col);
38
+ const classObj = {
39
+ 'fixed-cell': col.fixed,
40
+ ['fixed-cell--' + col.fixed]: col.fixed,
41
+ 'fixed-cell--shadow': showShadow,
42
+ };
43
+ colMap.set(colKeyGen(col), classObj);
44
+ });
45
+ return colMap;
46
+ });
27
47
 
28
48
  /** 处理固定列阴影 */
29
49
  function dealFixedColShadow() {
30
50
  if (!props.fixedColShadow) return;
31
- fixedShadowCols = [];
51
+ fixedShadowCols.value = [];
32
52
  // 找到最右边的固定列 findLast
33
53
  let lastLeftCol = null;
34
54
  for (let i = tableHeaderLast.value.length - 1; i >= 0; i--) {
@@ -42,7 +62,7 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
42
62
  let node: any = { __PARENT__: lastLeftCol };
43
63
  while ((node = node.__PARENT__)) {
44
64
  if (node.fixed) {
45
- fixedShadowCols.push(node);
65
+ fixedShadowCols.value.push(node);
46
66
  }
47
67
  }
48
68
 
@@ -51,27 +71,11 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
51
71
  node = { __PARENT__: lastRightCol };
52
72
  while ((node = node.__PARENT__)) {
53
73
  if (node.fixed) {
54
- fixedShadowCols.push(node);
74
+ fixedShadowCols.value.push(node);
55
75
  }
56
76
  }
57
77
  }
58
78
 
59
- /** 固定列class */
60
- function getFixedColClass(col: StkTableColumn<DT>): Record<string, boolean> {
61
- const { showR, showL } = fixedShadow.value;
62
- const showShadow =
63
- props.fixedColShadow &&
64
- col.fixed &&
65
- ((showL && col.fixed === 'left') || (showR && col.fixed === 'right')) &&
66
- fixedShadowCols.includes(col);
67
- const classObj = {
68
- 'fixed-cell': col.fixed,
69
- ['fixed-cell--' + col.fixed]: col.fixed,
70
- 'fixed-cell--shadow': showShadow,
71
- };
72
- return classObj;
73
- }
74
-
75
79
  /** 滚动条变化时,更新需要展示阴影的列 */
76
80
  function updateFixedShadow() {
77
81
  if (!props.fixedColShadow) return;
@@ -82,7 +86,7 @@ export function useFixedCol<DT extends Record<string, any>>({ props, tableHeader
82
86
 
83
87
  return {
84
88
  /** 固定列class */
85
- getFixedColClass,
89
+ fixedColClassMap,
86
90
  /** 处理固定列阴影 */
87
91
  dealFixedColShadow,
88
92
  /** 滚动条变化时,更新需要展示阴影的列 */
@@ -1,6 +1,6 @@
1
1
  import { CSSProperties, Ref, computed } from 'vue';
2
2
  import { Is_Legacy_Mode } from './const';
3
- import { StkTableColumn } from './types';
3
+ import { StkTableColumn, TagType } from './types';
4
4
  import { VirtualScrollStore, VirtualScrollXStore } from './useVirtualScroll';
5
5
  import { getColWidth } from './utils';
6
6
 
@@ -64,24 +64,25 @@ export function useFixedStyle<DT extends Record<string, any>>({
64
64
 
65
65
  return { refStore, colKeyStore };
66
66
  });
67
+
67
68
  /**
68
69
  * 固定列的style
69
70
  * @param tagType 1-th 2-td
70
71
  * @param col
71
72
  * @param depth 深度。tagType = 1时使用
72
73
  */
73
- function getFixedStyle(tagType: 1 | 2, col: StkTableColumn<any>, depth = 0): CSSProperties {
74
+ function getFixedStyle(tagType: TagType, col: StkTableColumn<DT>, depth = 0): CSSProperties {
74
75
  const { fixed } = col;
75
76
  const isFixedLeft = fixed === 'left';
76
77
  const style: CSSProperties = {};
77
78
  const { colKeyStore, refStore } = fixedColumnsPositionStore.value;
78
- // TD
79
+
79
80
  if (Is_Legacy_Mode) {
80
81
  style.position = 'relative';
81
82
  } else {
82
83
  style.position = 'sticky';
83
84
  }
84
- if (tagType === 1) {
85
+ if (tagType === TagType.TH) {
85
86
  // TH
86
87
  if (Is_Legacy_Mode) {
87
88
  style.top = virtualScroll.value.scrollTop + depth * props.rowHeight + 'px';
@@ -90,6 +91,7 @@ export function useFixedStyle<DT extends Record<string, any>>({
90
91
  }
91
92
  style.zIndex = isFixedLeft ? '5' : '4'; // 保证固定列高于其他单元格
92
93
  } else {
94
+ // TD
93
95
  style.zIndex = isFixedLeft ? '3' : '2';
94
96
  }
95
97
 
@@ -76,6 +76,9 @@ export function useHighlight({ props, tableContainer }: Params) {
76
76
  }
77
77
  });
78
78
 
79
+ // $*$ 兼容vue2响应
80
+ highlightRowStore.value = { ...highlightRowStore.value };
81
+
79
82
  if (highlightDimRowKeys.size > 0) {
80
83
  // 还有高亮的行,则下一次循环
81
84
  recursion();
@@ -111,16 +114,17 @@ export function useHighlight({ props, tableContainer }: Params) {
111
114
  /**
112
115
  * 高亮一行
113
116
  * @param rowKeyValues
117
+ * @param option.useCss 虚拟滚动时,高亮由js控制。如果仍想使用css 关键帧控制,则配置此项
114
118
  */
115
- function setHighlightDimRow(rowKeyValues: UniqKey[]) {
119
+ function setHighlightDimRow(rowKeyValues: UniqKey[], option: { useCss?: boolean } = {}) {
116
120
  if (!Array.isArray(rowKeyValues)) rowKeyValues = [rowKeyValues];
117
- if (props.virtual) {
121
+ if (props.virtual && !option.useCss) {
118
122
  // --------虚拟滚动用js计算颜色渐变的高亮方案
119
123
  const nowTs = Date.now(); // 重置渐变进度
120
124
  for (let i = 0; i < rowKeyValues.length; i++) {
121
125
  const rowKeyValue = rowKeyValues[i];
122
126
  highlightRowStore.value[rowKeyValue] = {
123
- bgc: '',
127
+ bgc: highlightFrom.value,
124
128
  bgc_progress: 0,
125
129
  bgc_progress_ms: nowTs,
126
130
  };