Cells
源码
vue
<template>
<div class="base-view">
<div style="width: 100%; height: 600px; border: 2px solid var(--el-color-border)">
<Grid
:columns="columns"
:list="list"
:options="{
border: true,
highlightSelectRow: true,
highlightSelectCol: true,
highlightSelectCell: true,
textOverflow: 'ellipsis',
...customConfig,
minRowHeight: minRowHeight,
}"
></Grid>
</div>
</div>
</template>
<script setup lang="tsx">
import { Grid, type Column, type ListItem } from 'vue-virt-grid';
import {
SelectCover,
SelectDropdown,
SelectView,
DateView,
DateCover,
DateDropdown,
LinkView,
PersonView,
CellType,
type TdData,
} from 'vue-virt-grid';
import { ElSelect, ElOption } from 'element-plus';
import 'element-plus/dist/index.css';
// const generateColumns = (length = 10, prefix = 'field-', props?: any) =>
// Array.from({ length }).map((_, columnIndex) => ({
// ...props,
// field: `${prefix}${columnIndex}`,
// title: `Title ${columnIndex}`,
// width: 200,
// }));
const generateList = (columns: Column[], length = 10000, prefix = 'row-') =>
Array.from({ length }).map((_, rowIndex) => {
return columns.reduce(
(rowData, column, columnIndex) => {
if (column.field === 'select' || column.field === 'select1') {
rowData[column.field] = 'key1,key2,key3,key4';
} else {
rowData[column.field] = `Row ${rowIndex} - Field ${columnIndex}`;
}
return rowData;
},
{
id: `${prefix}${rowIndex}`,
parentId: null,
},
);
});
const options = [
{ key: 'key1', value: '选项1', bg: '#ffe8e6' },
{ key: 'key2', value: '选项2', bg: '#e6f7ff' },
{ key: 'key3', value: '选项3', bg: 'rgb(2, 179, 161)' },
{ key: 'key4', value: '选项4', bg: 'rgb(2, 179, 161)' },
{ key: 'key5', value: '选项5', bg: 'rgb(2, 179, 161)' },
{ key: 'key6', value: '选项6', bg: 'rgb(2, 179, 161)' },
{ key: 'key7', value: '选项7', bg: 'rgb(2, 179, 161)' },
{ key: 'key8', value: '选项8', bg: 'rgb(2, 179, 161)' },
{ key: 'key9', value: '选项9', bg: 'rgb(2, 179, 161)' },
{ key: 'key10', value: '选项10', bg: 'rgb(2, 179, 161)' },
{ key: 'key11', value: '选项11', bg: 'rgb(2, 179, 161)' },
{ key: 'key12', value: '选项12', bg: 'rgb(2, 179, 161)' },
{ key: 'key13', value: '选项13', bg: 'rgb(2, 179, 161)' },
];
const minRowHeight = 36;
const columns: Column[] = [
{
field: 'text',
title: 'Text',
width: 200,
},
{
field: 'select',
title: '内部组件渲染',
width: 200,
type: 'select',
options: options,
},
{
field: 'select1',
title: '自定义渲染',
width: 200,
options: options,
cellRender: (tdData: TdData) => (
<SelectView height={minRowHeight} column={tdData.column} row={tdData.row} />
),
// 单击渲染
cellCoverRender: (tdData: TdData) => (
<SelectCover column={tdData.column} row={tdData.row} tdData={tdData} />
),
// 双击渲染
cellDropdownRender: (tdData: TdData) => (
<SelectDropdown column={tdData.column} row={tdData.row} tdData={tdData} />
),
},
{
field: 'select0',
title: '加载element-plus组件',
width: 200,
cellCoverRender: () => (
<ElSelect placeholder="Select" size="large" style="width: 100%">
<ElOption label="11" value="11" />
<ElOption label="22" value="22" />
</ElSelect>
// return {
// props: {},
// class: '',
// style: '',
// render: null,
// }
),
},
{
field: 'global-render',
title: '全局渲染器渲染',
width: 200,
type: 'custom',
},
{
field: 'date',
title: 'Date',
width: 200,
// cellRender: () => <DateView />,
// // 单击渲染
// cellCoverRender: () => <DateCover />,
// // 双击渲染
// cellDropdownRender: () => <DateDropdown />,
},
{
field: 'person',
title: 'Person',
width: 200,
cellRender: () => <PersonView />,
},
{
field: 'link',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link1',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link2',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link3',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link4',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link5',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link6',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link7',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link8',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link9',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link10',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link11',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link12',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link13',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link14',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link15',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link16',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link17',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link18',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link19',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link20',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link21',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link22',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link23',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link24',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link25',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link26',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link27',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link28',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link29',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link30',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link31',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link32',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link33',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link34',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link35',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link36',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link37',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link38',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link39',
title: 'Link',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'link40',
title: 'Link40',
width: 200,
cellRender: () => <LinkView />,
},
{
field: 'select111',
title: '自定义渲染',
width: 200,
cellRender: (tdData: any) => <SelectView column={tdData.column} row={tdData.row} />,
// 单击渲染
cellCoverRender: (tdData: any) => (
<SelectCover column={tdData.column} row={tdData.row} tdData={tdData} />
),
// 双击渲染
cellDropdownRender: (tdData: any) => (
<SelectDropdown column={tdData.column} row={tdData.row} tdData={tdData} />
),
},
];
const list: ListItem[] = generateList(columns, 200);
const customConfig: any = {
cellRender: (column: Column, row: ListItem) => {
if (column?.type === 'custom') {
// 自定义类型
return <div>global custom</div>;
}
},
cellCoverRender: (column: Column, row: ListItem) => {
if (column?.type === 'custom') {
// 自定义类型
return <div>global custom</div>;
}
},
cellDropdownRender: (column: Column, row: ListItem) => {
if (column?.type === 'custom') {
// 自定义类型
return <div>global custom</div>;
}
},
};
// TODO 单元格模式
// list[0].text = {
// // 实际值
// value: 'Text',
// // 渲染函数
// cellRender: (column: Column, row: ListItem) => <SelectView column={column} row={row} />,
// // 单击渲染
// cellCoverRender: (column: Column, row: ListItem, tdData: any) => (
// <SelectCover column={column} row={row} tdData={tdData} />
// ),
// // 双击渲染
// cellDropdownRender: (column: Column, row: ListItem, tdData: any) => (
// <SelectDropdown column={column} row={row} tdData={tdData} />
// ),
// };
</script>
<style lang="scss">
.base-view {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
</style>