1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- <template>
- <el-table-v2 fixed :columns="columns" :data="data" :width="700" :height="400">
- <template #row="props">
- <Row v-bind="props" />
- </template>
- </el-table-v2>
- </template>
- <script lang="tsx" setup>
- import { cloneVNode } from 'vue'
- 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(10)
- const data = generateData(columns, 200)
- const colSpanIndex = 1
- columns[colSpanIndex].colSpan = ({ rowIndex }) => (rowIndex % 4) + 1
- columns[colSpanIndex].align = 'center'
- const rowSpanIndex = 0
- columns[rowSpanIndex].rowSpan = ({ rowIndex }) =>
- rowIndex % 2 === 0 && rowIndex <= data.length - 2 ? 2 : 1
- const Row = ({ rowData, rowIndex, cells, columns }) => {
- const colSpan = columns[colSpanIndex].colSpan({ rowData, rowIndex })
- if (colSpan > 1) {
- let width = Number.parseInt(cells[colSpanIndex].props.style.width)
- for (let i = 1; i < colSpan; i++) {
- width += Number.parseInt(cells[colSpanIndex + i].props.style.width)
- cells[colSpanIndex + i] = null
- }
- const style = {
- ...cells[colSpanIndex].props.style,
- width: `${width}px`,
- backgroundColor: 'var(--el-color-primary-light-3)',
- }
- cells[colSpanIndex] = cloneVNode(cells[colSpanIndex], { style })
- }
- const rowSpan = columns[rowSpanIndex].rowSpan({ rowData, rowIndex })
- if (rowSpan > 1) {
- const cell = cells[rowSpanIndex]
- const style = {
- ...cell.props.style,
- backgroundColor: 'var(--el-color-danger-light-3)',
- height: `${rowSpan * 50}px`,
- alignSelf: 'flex-start',
- zIndex: 1,
- }
- cells[rowSpanIndex] = cloneVNode(cell, { style })
- } else {
- const style = cells[rowSpanIndex].props.style
- // override the cell here for creating a pure node without pollute the style
- cells[rowSpanIndex] = (
- <div style={{ ...style, width: `${style.width}px` }} />
- )
- }
- return cells
- }
- </script>
|