Skip to content

Commit c8f9dc2

Browse files
jevin98sleeprite
authored andcommitted
!476 fix(table): columns.titleSlot无效
* fix(table): columns.titleSlot无效
1 parent c0b3926 commit c8f9dc2

File tree

22 files changed

+489
-431
lines changed

22 files changed

+489
-431
lines changed

docs/src/document/zh-CN/components/table.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ const defaultToolbars = [
975975
| width | 宽度 | -- | -- | -- | -- |
976976
| minWidth | 最小宽度 | -- | `100px` | -- | -- |
977977
| sort | 排序,当值为字符串 `custom` 可通过 `sort-change` 事件自定义/服务端设置排序解结果 | `boolean`/ `string` | `false` | -- | -- |
978-
| titleSlot | 标题插槽 | 插槽参数 {column, columnIndex} | -- | -- | -- |
978+
| titleSlot | 标题自定义插槽 | `string` `function` 参数{column, columnIndex} | -- | -- | `2.22.1`新增`function` |
979979
| align | 对齐方式 | `string` | `left` | `left` `right` `center` | -- |
980980
| ellipsisTooltip | 当内容过长被隐藏时显示 tooltip | `boolean` | `false` | `true` `false` | -- |
981981
| ellipsisTooltipTheme | tooltip 主题 !!!建议替换为 `ellipsisTooltipProps.isDark` 属性,将在未来版本删除 | `string` | `light` | `dark` `light` | -- |

eslint.config.mjs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import antfu from "@antfu/eslint-config";
2-
import stylistic from "@stylistic/eslint-plugin";
32

43
export default antfu(
54
{
@@ -17,10 +16,15 @@ export default antfu(
1716
"docs/",
1817
"**/*.test.*",
1918
],
20-
},
2119

22-
stylistic.configs.customize({
23-
semi: true,
24-
quotes: "double",
25-
}),
20+
stylistic: {
21+
semi: true,
22+
quotes: "double",
23+
24+
},
25+
26+
rules: {
27+
"ts/no-unsafe-function-type": "off",
28+
},
29+
},
2630
);

packages/component/component/_components/render.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { defineComponent } from "vue";
44

55
type RenderFunc = (props: Record<string, unknown>) => VNodeTypes;
66

7+
export type Render = string | RenderFunc;
8+
79
export default defineComponent({
810
name: "LayRender",
911
inheritAttrs: false,
1012
props: {
1113
render: {
12-
type: [String, Function] as PropType<string | RenderFunc>,
14+
type: [String, Function] as PropType<Render>,
1315
},
1416
slots: {
1517
type: Object as PropType<Slots>,

packages/component/component/table/__tests__/table.test.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,4 +765,37 @@ describe("LayTable", () => {
765765
await operatorDoms[1].trigger("click");
766766
expect(name).toBe("张三2");
767767
});
768+
769+
test("columns titleSlot", async () => {
770+
const columns = [
771+
{ title: '', titleSlot: "titleSlot1", width: "80px", key: "name1" },
772+
{ title: '', titleSlot: () => ('titleSlot2'), width: "80px", key: "name2" },
773+
];
774+
775+
const dataSource = ref([]);
776+
777+
const wrapper = mount({
778+
setup() {
779+
return () => (
780+
<LayTable
781+
page={{ current: 1, limit: 10, total: 100 }}
782+
columns={columns}
783+
dataSource={dataSource.value}
784+
v-slots={{
785+
titleSlot1: ({ row }: any) => (
786+
'titleSlot1'
787+
),
788+
}}
789+
></LayTable>
790+
);
791+
},
792+
});
793+
794+
await nextTick()
795+
796+
const thS = wrapper.findAll(".layui-table-header .layui-table-header-wrapper tr th");
797+
798+
expect(thS[0].text()).toBe('titleSlot1')
799+
expect(thS[1].text()).toBe('titleSlot2')
800+
});
768801
});

packages/component/component/table/components/TableHeader.vue

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
<script setup lang="ts">
2-
import { inject } from "vue";
3-
import { type TableColumn, type SortType, sortType } from "../typing";
2+
import type { SortType, TableColumn } from "../typing";
3+
import LayRender from "@layui/component/component/_components/render";
44
import LayCheckboxV2 from "@layui/component/component/checkboxV2/index.vue";
55
66
import { isValueArray } from "@layui/component/utils";
7-
import { startResize } from "../hooks/useResize";
7+
8+
import { inject } from "vue";
89
import { LAY_TABLE_CONTEXT } from "../constant";
10+
import { startResize } from "../hooks/useResize";
11+
import { sortType } from "../typing";
912
1013
defineOptions({
1114
name: "LayTableHeader",
1215
});
1316
17+
defineProps<{
18+
lastLevelShowColumns: TableColumn[];
19+
hierarchicalColumns: TableColumn[][];
20+
tableBodyScrollWidth: number;
21+
}>();
22+
1423
const {
1524
tableProps,
1625
tableEmits,
26+
tableSlots,
1727
1828
tableDataSource,
1929
tableRef,
@@ -29,46 +39,37 @@ const {
2939
commonGetStylees,
3040
} = inject(LAY_TABLE_CONTEXT)!;
3141
32-
defineProps<{
33-
lastLevelShowColumns: TableColumn[];
34-
hierarchicalColumns: TableColumn[][];
35-
tableBodyScrollWidth: number;
36-
}>();
37-
38-
const thSort = (e: Event, column: any) => {
42+
function thSort(e: Event, column: any) {
3943
const spanDom = (e.currentTarget as HTMLElement).querySelector(
40-
"span[lay-sort]"
44+
"span[lay-sort]",
4145
) as HTMLSpanElement;
4246
43-
if (!spanDom) return;
47+
if (!spanDom)
48+
return;
4449
4550
const sortValue = spanDom.getAttribute("lay-sort") as SortType;
4651
4752
const currentIndex = sortType.indexOf(sortValue);
4853
const nextSort = sortType[(currentIndex + 1) % sortType.length];
4954
5055
baseSort(spanDom, column, nextSort);
51-
};
56+
}
5257
53-
const iconSort = (e: Event, column: any, sort: Exclude<SortType, "">) => {
58+
function iconSort(e: Event, column: any, sort: Exclude<SortType, "">) {
5459
const spanDom = (e.target as HTMLElement).parentNode as HTMLSpanElement;
5560
5661
const sortValue = spanDom.getAttribute("lay-sort") as SortType;
5762
5863
baseSort(spanDom, column, sortValue !== sort ? sort : "");
59-
};
64+
}
6065
6166
/**
6267
*
6368
* @param spanDom 包含lay-sort属性的span dom
6469
* @param column column
6570
* @param nextSort 下一次的sort
6671
*/
67-
const baseSort = (
68-
spanDom: HTMLSpanElement,
69-
column: any,
70-
nextSort: SortType
71-
) => {
72+
function baseSort(spanDom: HTMLSpanElement, column: any, nextSort: SortType) {
7273
const { key, sort } = column;
7374
7475
removeAllSortState();
@@ -79,15 +80,15 @@ const baseSort = (
7980
}
8081
8182
tableEmits("sort-change", key, nextSort);
82-
};
83+
}
8384
84-
const defaultSort = (key: string, sortType: SortType) => {
85+
function defaultSort(key: string, sortType: SortType) {
8586
switch (sortType) {
8687
case "":
8788
tableDataSource.splice(
8889
0,
8990
tableDataSource.length,
90-
...tableProps.dataSource
91+
...tableProps.dataSource,
9192
);
9293
break;
9394
case "asc":
@@ -97,38 +98,38 @@ const defaultSort = (key: string, sortType: SortType) => {
9798
tableDataSource.sort((a: any, b: any) => b[key] - a[key]);
9899
break;
99100
}
100-
};
101+
}
101102
102103
// 清空所有的sort状态
103-
const removeAllSortState = () => {
104+
function removeAllSortState() {
104105
const sortElements = tableRef.value!.querySelectorAll("[lay-sort]");
105106
if (sortElements && sortElements.length > 0) {
106107
sortElements.forEach((element) => {
107108
element.setAttribute("lay-sort", "");
108109
});
109110
}
110-
};
111+
}
111112
</script>
112113

113114
<template>
114115
<div
115116
class="layui-table-header"
116117
:style="[{ 'padding-right': `${tableBodyScrollWidth}px` }]"
117118
>
118-
<div class="layui-table-header-wrapper" ref="tableHeaderRef">
119+
<div ref="tableHeaderRef" class="layui-table-header-wrapper">
119120
<table
121+
ref="tableHeaderTableRef"
120122
class="layui-table"
121123
:lay-size="tableProps.size"
122124
:lay-skin="tableProps.skin"
123-
ref="tableHeaderTableRef"
124125
>
125126
<colgroup>
126127
<col
127128
v-for="(column, index) in lastLevelShowColumns"
128129
:key="column.key || column.type || index"
129130
:width="column.width"
130131
:style="{ minWidth: column.minWidth }"
131-
/>
132+
>
132133
</colgroup>
133134
<thead>
134135
<tr
@@ -153,9 +154,9 @@ const removeAllSortState = () => {
153154
:style="commonGetStylees(column)"
154155
@click="thSort($event, column)"
155156
>
156-
<template v-if="column.type == 'checkbox'">
157-
<layCheckboxV2
158-
:modelValue="selectedState.allMSelected.value"
157+
<template v-if="column.type === 'checkbox'">
158+
<LayCheckboxV2
159+
:model-value="selectedState.allMSelected.value"
159160
:is-indeterminate="selectedState.someMSelected.value"
160161
skin="primary"
161162
value="all"
@@ -164,13 +165,14 @@ const removeAllSortState = () => {
164165
</template>
165166
<template v-else>
166167
<span>
167-
<template v-if="column.titleSlot">
168-
<slot
169-
:name="column.titleSlot"
170-
:column="column"
171-
:columnIndex="columnIndex"
172-
></slot>
173-
</template>
168+
<LayRender
169+
v-if="column.titleSlot"
170+
:slots="tableSlots"
171+
:render="column.titleSlot"
172+
:column="column"
173+
:column-index="columnIndex"
174+
/>
175+
174176
<template v-else>
175177
{{ column.title }}
176178
</template>
@@ -186,22 +188,22 @@ const removeAllSortState = () => {
186188
"
187189
>
188190
<i
189-
@click.stop="iconSort($event, column, 'asc')"
190191
class="layui-edge layui-table-sort-asc"
191192
title="升序"
192-
></i>
193+
@click.stop="iconSort($event, column, 'asc')"
194+
/>
193195
<i
194-
@click.stop="iconSort($event, column, 'desc')"
195196
class="layui-edge layui-table-sort-desc"
196197
title="降序"
197-
></i>
198+
@click.stop="iconSort($event, column, 'desc')"
199+
/>
198200
</span>
199201
</template>
200202
<!-- 列宽拖动区 -->
201203
<div
202204
v-if="
203-
(tableProps.resize || column.resize) &&
204-
!isValueArray(column.children)
205+
(tableProps.resize || column.resize)
206+
&& !isValueArray(column.children)
205207
"
206208
class="lay-table-cols-resize"
207209
@mousedown.stop="
@@ -210,11 +212,11 @@ const removeAllSortState = () => {
210212
column,
211213
tableHeaderTableRef,
212214
tableBodyTableRef,
213-
tableTotalTableRef
215+
tableTotalTableRef,
214216
)
215217
"
216218
@click.stop
217-
></div>
219+
/>
218220
</th>
219221
</template>
220222
</tr>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy