mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-12 12:25:22 +08:00
131 lines
3.2 KiB
Vue
131 lines
3.2 KiB
Vue
<template>
|
|
<el-table-v2
|
|
fixed
|
|
:columns="fixedColumns"
|
|
:data="data"
|
|
:header-height="[50, 40, 50]"
|
|
:header-class="headerClass"
|
|
:width="700"
|
|
:height="400"
|
|
>
|
|
<template #header="props">
|
|
<customized-header v-bind="props" />
|
|
</template>
|
|
</el-table-v2>
|
|
</template>
|
|
<script lang="tsx" setup>
|
|
import { TableV2FixedDir, TableV2Placeholder } from 'element-plus'
|
|
|
|
import type { FunctionalComponent } from 'vue'
|
|
import type {
|
|
HeaderClassNameGetter,
|
|
TableV2CustomizedHeaderSlotParam,
|
|
} from 'element-plus'
|
|
|
|
const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
|
|
Array.from({ length }).map((_, columnIndex) => ({
|
|
...props,
|
|
key: `${prefix}${columnIndex}`,
|
|
dataKey: `${prefix}${columnIndex}`,
|
|
title: `Column ${columnIndex}`,
|
|
width: 150,
|
|
}))
|
|
|
|
const generateData = (
|
|
columns: ReturnType<typeof generateColumns>,
|
|
length = 200,
|
|
prefix = 'row-'
|
|
) =>
|
|
Array.from({ length }).map((_, rowIndex) => {
|
|
return columns.reduce(
|
|
(rowData, column, columnIndex) => {
|
|
rowData[column.dataKey] = `Row ${rowIndex} - Col ${columnIndex}`
|
|
return rowData
|
|
},
|
|
{
|
|
id: `${prefix}${rowIndex}`,
|
|
parentId: null,
|
|
}
|
|
)
|
|
})
|
|
const columns = generateColumns(15)
|
|
const data = generateData(columns, 200)
|
|
|
|
const fixedColumns = columns.map((column, columnIndex) => {
|
|
let fixed: TableV2FixedDir | undefined = undefined
|
|
if (columnIndex < 3) fixed = TableV2FixedDir.LEFT
|
|
if (columnIndex > 12) fixed = TableV2FixedDir.RIGHT
|
|
return { ...column, fixed, width: 100 }
|
|
})
|
|
|
|
const CustomizedHeader: FunctionalComponent<
|
|
TableV2CustomizedHeaderSlotParam
|
|
> = ({ cells, columns, headerIndex }) => {
|
|
if (headerIndex === 2) return cells
|
|
|
|
const groupCells = [] as typeof cells
|
|
let width = 0
|
|
let idx = 0
|
|
|
|
columns.forEach((column, columnIndex) => {
|
|
if (column.placeholderSign === TableV2Placeholder)
|
|
groupCells.push(cells[columnIndex])
|
|
else {
|
|
width += cells[columnIndex].props!.column.width
|
|
idx++
|
|
|
|
const nextColumn = columns[columnIndex + 1]
|
|
if (
|
|
columnIndex === columns.length - 1 ||
|
|
nextColumn.placeholderSign === TableV2Placeholder ||
|
|
idx === (headerIndex === 0 ? 4 : 2)
|
|
) {
|
|
groupCells.push(
|
|
<div
|
|
class="flex items-center justify-center custom-header-cell"
|
|
role="columnheader"
|
|
style={{
|
|
...cells[columnIndex].props!.style,
|
|
width: `${width}px`,
|
|
}}
|
|
>
|
|
Group width {width}
|
|
</div>
|
|
)
|
|
width = 0
|
|
idx = 0
|
|
}
|
|
}
|
|
})
|
|
return groupCells
|
|
}
|
|
|
|
const headerClass = ({
|
|
headerIndex,
|
|
}: Parameters<HeaderClassNameGetter<any>>[0]) => {
|
|
if (headerIndex === 1) return 'el-primary-color'
|
|
return ''
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.el-el-table-v2__header-row .custom-header-cell {
|
|
border-right: 1px solid var(--el-border-color);
|
|
}
|
|
|
|
.el-el-table-v2__header-row .custom-header-cell:last-child {
|
|
border-right: none;
|
|
}
|
|
|
|
.el-primary-color {
|
|
background-color: var(--el-color-primary);
|
|
color: var(--el-color-white);
|
|
font-size: 14px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.el-primary-color .custom-header-cell {
|
|
padding: 0 4px;
|
|
}
|
|
</style>
|