SimpleTable
SimpleTable is a very lightweight table component that uses only HTML table
to implement all its features.
TIP
The component needs to be wrapped with <client-only></client-only>
tags when used in SSR (e.g., Nuxt) and SSG (e.g., VitePress).
WARNING
The default Vitepress theme has some interference with the component's styles, but it does not affect functionality.
Basic
For text overflow settings, refer to:
用户名 | 年龄 | 单位 | 简介 | 操作 | |
---|---|---|---|---|---|
柏庐 | 20 | 某个公司 | 来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计 | ||
军结 | 22 | 某个公司 | 经验丰富的前端工程师 | ||
钞洋 | 28 | 某个公司 | 90后交互设计师 |
Example Code
<template>
<epp-simple-table :cols="cols" :data="tableData" @row-click="rowClicked" @cell-click="cellClicked">
<template #firstCol>
<el-checkbox v-model="selectedAll" :indeterminate="isIndeterminate" @change="selectAll" />
</template>
<template #tableIndex="{ row }">
<el-checkbox v-model="selectedRows" :value="row.id" @change="selectRow(row.id)">{{ '' }}</el-checkbox>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import type { ColumnType } from 'element-plus-plus';
const selectedAll = ref(false);
const selectedRows = ref<number[]>([]);
const isIndeterminate = ref(false);
const tableData = ref([
{
id: 1,
name: '柏庐',
sex: '女',
org: '某个公司',
des: '来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计',
otherInfo: {
age: 20,
},
},
{
id: 2,
name: '军结',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
otherInfo: {
age: 22,
},
},
{
id: 3,
name: '钞洋',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
otherInfo: {
age: 28,
},
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex', headerSlotName: 'firstCol', width: '3em' },
{ title: '用户名', prop: 'name' },
{ title: '年龄', prop: 'otherInfo.age' },
{ title: '单位', prop: 'org', align: 'center' },
{
title: '简介',
prop: 'des',
align: 'center',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const selectAll = () => {
if (selectedAll.value) {
selectedRows.value.splice(0, selectedRows.value.length);
selectedRows.value.push(...tableData.value.map((d) => d.id));
isIndeterminate.value = false;
} else {
selectedRows.value.splice(0, selectedRows.value.length);
}
};
const selectRow = () => {
selectedAll.value = selectedRows.value.length === tableData.value.length;
if (selectedRows.value.length > 0 && selectedAll.value == false) {
isIndeterminate.value = true;
} else {
isIndeterminate.value = false;
}
};
const rowClicked = (row: Record<string, any>, rowIndex: number, event: Event) => {
console.log('rowClicked', row, rowIndex, event);
};
const cellClicked = (row: Record<string, any>, col: ColumnType, rowIndex: number, colIndex: number, event: Event) => {
console.log('cellClicked', row, col, rowIndex, colIndex, event);
};
</script>
Border Style
The border
prop can add border styles to the table.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<el-select v-model="value" clearable placeholder="请选择" class="w-200 m-b-lg">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<epp-simple-table :cols="cols" :data="tableData" :border="value" padding="0">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const options = ref([
{
value: 'borderless',
label: 'borderless',
},
{
value: 'border-x',
label: 'border-x',
},
{
value: 'border-y',
label: 'border-y',
},
{
value: 'bordered',
label: 'bordered',
},
]);
const value = ref('borderless');
</script>
Spacing Settings
The padding
prop can add different spacing sizes to the table, while cell-padding
can set the spacing size for TDs.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<el-select v-model="value" clearable placeholder="请选择表格填充" class="m-b-md w-200">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="value2" clearable placeholder="请选择单元格填充" class="m-l-md m-b-md w-200">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<epp-simple-table :cols="cols" :data="tableData" border="border-x" :padding="value" :cell-padding="value2">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const options = ref([
{
value: '0',
label: 'none',
},
{
value: '8px',
label: '8px',
},
{
value: '12px',
label: '12px',
},
{
value: '16px',
label: '16px',
},
{
value: '20px',
label: '20px',
},
{
value: '24px',
label: '24px',
},
]);
const value = ref('0');
const value2 = ref('0');
</script>
Hover Style
The hover
prop can display a background color when hovering over a row.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<epp-simple-table :cols="cols" :data="tableData" cross-hover hover>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
</script>
Stripe Style
The stripe
prop can create a striped table to distinguish between different rows of data.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
stripe
also accepts even
or odd
props to set the order of stripe display. The default is odd
.
<template>
<epp-simple-table :cols="cols" :data="tableData" stripe>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
</script>
Size Modifier
The size
prop can set the size of the table.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<el-select v-model="value" clearable placeholder="请选择" class="m-b-md w-200">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<epp-simple-table :cols="cols" :data="tableData" :size="value" class="borderless-last">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const options = ref([
{
value: 'sm',
label: 'sm',
},
{
value: 'md',
label: 'md',
},
{
value: 'lg',
label: 'lg',
},
]);
const value = ref('md');
</script>
Drag to Resize Columns
Setting the resize
prop to true
allows dragging the table header columns to change their width.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<epp-simple-table :cols="cols" :data="tableData" border="bordered" resize>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex', width: '4em' },
{ title: '用户名', prop: 'name', width: '8em' },
{ title: '性别', prop: 'sex', width: '4em' },
{ title: '单位', prop: 'org', width: '' },
{ title: '简介', prop: 'des', width: '' },
{ title: '操作', slotName: 'handle', align: 'center', width: '6em' },
]);
</script>
List Style
list
can present the traditional table as a list.
The list style adds rounded corners to each table row. You can also customize the spacing between each row, for example: gap="var(--xs)"
.
<template>
<div style="background-color: #25303f; height: 240px; padding: 12px;">
<el-scrollbar style="height: 200px">
<epp-simple-table :cols="cols" :data="tableData" gap-y="8px" list fixed-header>
<template #tableIndex="{ row }">
{{ row.icon }}
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</el-scrollbar>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
icon: 'Briefcase',
},
{
id: 2,
name: '李四',
sex: '男',
org: '某个公司',
des: '来自中国',
icon: 'ChartPie',
},
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
icon: 'Archive',
},
{ id: 4, name: '李四2', sex: '男', org: '某个公司', des: '来自中国', icon: 'Archive' },
{ id: 5, name: '李四3', sex: '男', org: '某个公司', des: '来自中国', icon: 'Archive' },
{ id: 6, name: '李四4', sex: '男', org: '某个公司', des: '来自中国', icon: 'Archive' },
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
</script>
Fixed Header
Adding the fixed-header
prop to the SimpleTable component can fix the header to the top.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! | |
4 | 李四2 | 男 | 某个公司 | 来自中国 | |
5 | 李四3 | 男 | 某个公司 | 来自中国 | |
6 | 李四4 | 男 | 某个公司 | 来自中国 |
Example Code
<template>
<div class="table-scroll" style="height: 200px">
<epp-simple-table :cols="cols" :data="tableData" border="bordered" fixed-header>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
{ id: 4, name: '李四2', sex: '男', org: '某个公司', des: '来自中国' },
{ id: 5, name: '李四3', sex: '男', org: '某个公司', des: '来自中国' },
{ id: 6, name: '李四4', sex: '男', org: '某个公司', des: '来自中国' },
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
</script>
Fixed Columns
- Adding the
fixed
prop to a column can fix it. You can also passleft
orright
to control where it is fixed. For example,fixed: 'left'
. - The
fixed
prop can also be of typeobject
for detailed control of thefixed
distance. Whenfixed
is of typeobject
, thedistance
field can be set toauto
, which will automatically calculate the fixed distance based on the column width. - It is recommended that when using this,
distance
should either be set to specific values or set toauto
. Mixing them may cause calculation errors.
序号 | 姓名 | 性别 | 工号 | 职级 | 司龄 | 字段1 | 字段2 | 右自动固定 | 描述 | 单位 | 操作 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 王二麻子 | 男 | 478343 | P8 | 10 | 测试字段1 | 测试字段2 | 测试字段3 | 来自中国南方的温暖城市! | 某个公司 | |
2 | 李四 | 男 | 238343 | P6 | 3 | 测试字段1 | 测试字段2 | 测试字段3 | 来自中国 | 某个公司 | |
3 | 张三 | 男 | 178343 | P7 | 5 | 测试字段1 | 测试字段2 | 测试字段3 | 来自中国北方的寒冷的城市! | 某个公司 |
Example Code
<template>
<div class="table-scroll scroll-column">
<epp-simple-table :cols="cols" :data="tableData" border="border-x">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
no: '478343',
level: 'P8',
years: 10,
field1: '测试字段1',
field2: '测试字段2',
field3: '测试字段3',
},
{
id: 2,
name: '李四',
sex: '男',
org: '某个公司',
des: '来自中国',
no: '238343',
level: 'P6',
years: 3,
field1: '测试字段1',
field2: '测试字段2',
field3: '测试字段3',
},
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
no: '178343',
level: 'P7',
years: 5,
field1: '测试字段1',
field2: '测试字段2',
field3: '测试字段3',
},
]);
// 序号 slot名称唯一 tableIndex。 width: 设置宽度。align: 对齐方式。showTooltip: td是否一行显示,超出tooptip
const cols = ref([
{ title: '序号', prop: '', slotName: 'tableIndex', fixed: 'left', minWidth: '50px' },
{ title: '姓名', prop: 'name', showTooltip: true, minWidth: '150px' },
{ title: '性别', prop: 'sex', width: '50px' },
{ title: '工号', prop: 'no', showTooltip: true, minWidth: '120px', fixed: { position: 'left', distance: 'auto' } },
{ title: '职级', prop: 'level' },
{ title: '司龄', prop: 'years' },
{ title: '字段1', prop: 'field1' },
{ title: '字段2', prop: 'field2' },
{ title: '右自动固定', prop: 'field3', fixed: { position: 'right', distance: 'auto' } },
{ title: '描述', prop: 'des', showTooltip: true, minWidth: '400px' },
{ title: '单位', prop: 'org', showTooltip: true, minWidth: '150px', fixed: { position: 'right', distance: 'auto' } },
{
title: '操作',
prop: '',
slotName: 'handle',
align: 'center',
fixed: 'right',
},
]);
</script>
Fixed Rows
Fixed row effect can also be achieved through the cellStyle
prop.
序号 | 姓名 | 性别 | 单位 | 描述 | 操作 |
---|---|---|---|---|---|
0 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
3 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
4 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
5 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
6 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
7 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
8 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
9 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
10 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
11 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
12 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
13 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
14 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
15 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
16 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
17 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
18 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
19 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
20 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
21 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! |
Example Code
<template>
<div class="table-scroll" style="height: 200px">
<epp-simple-table :cols="cols" :data="tableData" border="border-x" fixed-header :cell-style="cellStyle">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let idx = 0;
const row = {
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
};
const tableData = ref(new Array(22).fill(0).map((_) => Object.assign(JSON.parse(JSON.stringify(row)), { id: idx++ })));
const cols = ref([
{ title: '序号', prop: '', slotName: 'tableIndex' },
{ title: '姓名', prop: 'name', showTooltip: true, width: '100px' },
{ title: '性别', prop: 'sex', width: '50px' },
{ title: '单位', prop: 'org', showTooltip: true, width: '150px' },
{ title: '描述', prop: 'des', showTooltip: true, width: '400px' },
{ title: '操作', prop: '', slotName: 'handle', align: 'center' },
]);
// 固定5倍数的行
const cellStyle = ({ rowIndex }: { rowIndex: number }) => {
return rowIndex % 5 === 0
? {
backgroundColor: 'var(--el-fill-color-darker)',
zIndex: 10,
position: 'sticky',
top: `48px`, // 48为表格头的高度
}
: {};
};
</script>
Fixed Header and Columns
The header and columns can be fixed simultaneously.
Example Code
<template>
<el-scrollbar height="200px">
<epp-simple-table :cols="cols" :data="tableData" border="border-x" fixed-header>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</el-scrollbar>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{ id: 1, name: '费文轩', sex: '男', org: '14933867329', des: '安徽省六安市东港镇港下锡港东路8栋1204室' },
{ id: 2, name: '刘林', sex: '男', org: '11381484641', des: '内蒙锡林浩特市北六门村南河街8栋1204室' },
{ id: 3, name: '金玥傲', sex: '男', org: '15000688905', des: '黑龙江省北安市三岔路浦沅宿舍131号' },
{ id: 4, name: '王武', sex: '男', org: '18102220035', des: '湖北省洪湖市东五条路林机小区948号' },
{ id: 5, name: '卞嘉怡', sex: '女', org: '11022218210', des: '山东省招远市并州北路2条8号' },
{ id: 6, name: '和文杰', sex: '男', org: '12548097666', des: '陕西省安康市金国里506号517房' },
{ id: 7, name: '潘瑞堂', sex: '男', org: '12065726257', des: '安徽省天长市金霞街道国际商业中心121号' },
{ id: 8, name: '关爽', sex: '女', org: '15570593023', des: '四川省简阳市前进路506号517房' },
]);
// 序号 slot名称唯一 tableIndex。 width: 设置宽度。align: 对齐方式。showTooltip: td是否一行显示,超出tooptip
const cols = ref([
{ title: '#', prop: '', slotName: 'tableIndex', minWidth: '4em' },
{ title: '姓名', prop: 'name', minWidth: '7em', fixed: 'left' },
{ title: '性别', prop: 'sex', minWidth: '6em' },
{ title: '手机号', prop: 'org', minWidth: '10em' },
{ title: '住址', prop: 'des', minWidth: '26em' },
{
title: '操作',
prop: '',
slotName: 'handle',
align: 'center',
fixed: 'right',
},
]);
</script>
Pull-Down to Load More
With the Scrollbar component, pull-down to load more can be implemented.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! | |
4 | 张三2 | 男 | 某个公司 | 来自中国北方的寒冷的城市! | |
Loading |
Example Code
<template>
<div ref="divWrapper" style="height: 200px; overflow-y: scroll">
<epp-simple-table :cols="cols" :data="tableData" border="border-x" fixed-header>
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
<template v-if="hadMoreData" #more>
<template v-if="loading">
<el-space size="large">
<epp-spinner size="16px" />
<span>正在加载...</span>
</el-space>
</template>
</template>
</epp-simple-table>
</div>
</template>
<script setup lang="ts">
import { computed, ref, toRefs, watch } from 'vue';
import { useScroll } from '@vueuse/core';
const divWrapper = ref();
let count = 1;
function id() {
return count++;
}
const data = [
{
id: id(),
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: id(), name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: id(),
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
{
id: id(),
name: '张三2',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
];
const loading = ref(false);
const tableData = ref(JSON.parse(JSON.stringify(data)));
const cols = ref([
{ title: '#', slotName: 'tableIndex', width: '8%' },
{ title: '用户名', prop: 'name', width: '15%' },
{ title: '性别', prop: 'sex', width: '8%' },
{ title: '单位', prop: 'org', width: '20%' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center', width: '10%' },
]);
const hadMoreData = computed(() => tableData.value.length < 12);
const loadMore = () => {
if (loading.value || !hadMoreData.value) return;
loading.value = true;
window.setTimeout(() => {
const moreData = JSON.parse(JSON.stringify(data));
moreData.forEach((d: any) => {
d.id = id();
d.name = d.name + d.id;
});
tableData.value.push(...moreData);
loading.value = false;
}, 300);
};
const { arrivedState } = useScroll(divWrapper, { behavior: 'smooth' });
const { bottom } = toRefs(arrivedState);
watch(bottom, () => {
if (bottom.value) {
loadMore();
}
});
</script>
Remove Header
The show-header
prop can remove the header, making it display as a pure list style.
1 | 王二麻子 | 男 | 某个公司 | 来自中国南方的温暖城市! | |
2 | 李四 | 男 | 某个公司 | 来自中国 | |
3 | 张三 | 男 | 某个公司 | 来自中国北方的寒冷的城市! |
Example Code
<template>
<epp-simple-table :cols="cols" :data="tableData" hover :show-header="false">
<template #tableIndex="{ rowIndex }">
<span>{{ rowIndex + 1 }}</span>
</template>
<template #handle>
<el-button link type="primary">修改</el-button>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{ id: 2, name: '李四', sex: '男', org: '某个公司', des: '来自中国' },
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des' },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
</script>
Sorting
You can restore the default sorting by continuously clicking the same sorting icon. If you want to customize the column header but still use the default sorting icon, destructure the SortableIcon component from the SimpleTable component in non-setup syntax; for setup syntax, please refer to the following source code.
自定义列 | 用户名 | 性别 | 单位 | 简介 |
---|---|---|---|---|
1 | 范xxxx | 女 | 某个公司 | 来自安全应急UED的设计师来自安全应急UED的设计 |
2 | xxx | 男 | 某个公司 | 经验丰富的前端工程师 |
3 | 王ssss | 男 | 某个公司 | 90后交互设计师 |
You can set the sortable
prop in the column. The value can be: true / false / 'descending' / 'ascending'
. Handle data sorting by listening to the sort-change
event.
<template>
<epp-simple-table :cols="cols" :data="tableData" @sort-change="sortChange">
<template #index>
自定义列
<EppSimpleTable.SortableIcon sortable @sort-change="(val) => sortChange('id', val)" />
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { EppSimpleTable } from 'element-plus-plus';
const defaultData = [
{
id: 1,
name: '范xxxx',
sex: '女',
org: '某个公司',
des: '来自安全应急UED的设计师来自安全应急UED的设计',
},
{
id: 2,
name: 'xxx',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
},
{
id: 3,
name: '王ssss',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
},
];
const tableData = ref(JSON.parse(JSON.stringify(defaultData)));
const cols = ref([
{ title: '序号', prop: 'id', headerSlotName: 'index' },
{ title: '用户名', prop: 'name', sortable: true },
{ title: '性别', prop: 'sex', sortable: false },
{ title: '单位', prop: 'org', sortable: 'descending' },
{
title: '简介',
prop: 'des',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
sortable: 'ascending',
},
]);
const sortChange = (prop: string, sort: string) => {
// 仅作为示例,实际项目需要通过调取后台API实现
console.log('soring...', prop, sort);
if (sort) {
tableData.value.sort((d1: any, d2: any) => {
const result = String(d1[prop]).localeCompare(String(d2[prop]));
return sort === 'ascending' ? result : result * -1;
});
} else {
tableData.value = JSON.parse(JSON.stringify(defaultData));
}
};
</script>
Filtering
If you want to customize the column header but still use the default sorting icon, destructure the FilterIcon component from the SimpleTable component in non-setup syntax; for setup syntax, please refer to the following source code.
自定义列 | 用户名 | 单位 | 简介 | 操作 |
---|---|---|---|---|
1 | 范xx | 某个公司 | 来自安全应急UED的设计师来自安全应急UED的设计 | |
2 | xxx | 某个公司 | 经验丰富的前端工程师 | |
3 | 王xxx | 某个公司 | 90后交互设计师 |
You can set the filter
object in the column, providing slotName
(required), placement
(refer to the Popover documentation), and popperClass
properties. The close
method is provided in the slot to manually close the pop-up.
<template>
<epp-simple-table :cols="cols" :data="tableData">
<template #filterSlot="{ close }">
<el-space direction="vertical" size="large">
<el-space direction="vertical" size="large">
<el-checkbox v-mode="selectedItems" value="1">条件1</el-checkbox>
<el-checkbox v-mode="selectedItems" value="2">条件2</el-checkbox>
<el-checkbox v-mode="selectedItems" value="3">条件3</el-checkbox>
</el-space>
<el-button type="primary" size="sm" class="m-t-md" @click="close">确定</el-button>
</el-space>
</template>
<template #index>
自定义列
<EppSimpleTable.FilterIcon placement="right">
<template #default="{ close }">
<el-space direction="vertical" size="large">
<el-space direction="vertical" size="large">
<el-checkbox v-mode="selectedItems" value="1">条件1</el-checkbox>
<el-checkbox v-mode="selectedItems" value="2">条件2</el-checkbox>
<el-checkbox v-mode="selectedItems" value="3">条件3</el-checkbox>
</el-space>
<el-button type="primary" size="sm" class="m-t-md" @click="close">确定</el-button>
</el-space>
</template>
</EppSimpleTable.FilterIcon>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { EppSimpleTable } from 'element-plus-plus';
const tableData = ref([
{
id: 1,
name: '范xx',
sex: '女',
org: '某个公司',
des: '来自安全应急UED的设计师来自安全应急UED的设计',
},
{
id: 2,
name: 'xxx',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
},
{
id: 3,
name: '王xxx',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
},
]);
const cols = ref([
{ title: '序号', prop: 'id', headerSlotName: 'index' },
{
title: '用户名',
prop: 'name',
filter: {
slotName: 'filterSlot',
placement: 'top',
popperClass: 'test-filter-slot',
},
},
{ title: '单位', prop: 'org' },
{
title: '简介',
prop: 'des',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
filter: { slotName: 'filterSlot' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const selectedItems = ref<string[]>([]);
</script>
Highlight Row
Use a color block to indicate when a single row of data is selected.
用户名 | 性别 | 单位 | 简介 | 操作 | |
---|---|---|---|---|---|
1 | 范xxxx | 女 | 某个公司 | 来自安全应急UED的设计师来自安全应急UED的设计 | |
2 | xxx | 男 | 某个公司 | 经验丰富的前端工程师 | |
3 | 王ssss | 男 | 某个公司 | 90后交互设计师 |
The SimpleTable component provides single selection support. You only need to configure the highlight-current-row
prop to achieve single selection. The current-change
event then manages the event triggered when selected. It will pass in currentRow
and oldCurrentRow
.
<template>
<epp-simple-table
ref="tableRef"
:cols="cols"
:data="tableData"
highlight-current-row
@current-change="currentChange"
@row-click="rowClick"
/>
<br />
<el-button class="m-r-md" @click="setCurrent(tableData[0])">选中第一行</el-button>
<el-button @click="setCurrent()">取消选择</el-button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableRef = ref();
const tableData = ref([
{
id: 1,
name: '范xxxx',
sex: '女',
org: '某个公司',
des: '来自安全应急UED的设计师来自安全应急UED的设计',
},
{
id: 2,
name: 'xxx',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
},
{
id: 3,
name: '王ssss',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
},
]);
const cols = ref([
{ title: '序号', prop: 'id', headerSlotName: 'index' },
{
title: '用户名',
prop: 'name',
sortable: true,
filter: {
slotName: 'filterSlot',
placement: 'top',
popperClass: 'test-filter-slot',
},
},
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{
title: '简介',
prop: 'des',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
filter: { slotName: 'filterSlot' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const currentChange = (now: Record<string, any>, old: Record<string, any>) => {
console.log(now, old);
};
const rowClick = () => {
console.log('row-click');
};
const setCurrent = (row?: Record<string, any>) => {
tableRef.value.setCurrentRow(row);
};
</script>
Expand Row
When there is too much row content and you don't want to display a horizontal scrollbar, you can use the SimpleTable expand row feature. You can define multiple columns to expand simultaneously.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
点我展开 / 范xx | 女 | 某个公司 | 来自安全应急UED的设计师来自安全应急UED的设计 | ||
某个公司 / 来自安全应急UED的设计师来自安全应急UED的设计 | |||||
点我展开 / xxx | 男 | 某个公司 | 经验丰富的前端工程师 | ||
手工展开数据 | |||||
点我展开 / 王xx | 男 | 某个公司 | 90后交互设计师 |
You can enable the expand row feature by setting the expand
object and slot. The expand
object has two properties: slotName
and hideLabel
. hideLabel
defaults to false
.
<template>
<epp-simple-table ref="tableRef" :cols="cols" :data="tableData" :expand-row-keys="['1index', '2nameExpand']">
<template #index="{ row }">
<p>{{ row.org }} / {{ row.des }}</p>
</template>
<template #name="{ row }"> <a href="javascript:;" @click="expand(row)">点我展开</a> / {{ row.name }} </template>
<template #nameExpand>
<p>手工展开数据</p>
</template>
<template #des="{ row }">
<p>{{ row.sex }} / {{ row.des }}</p>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableRef = ref();
const tableData = ref([
{
id: 1,
name: '范xx',
sex: '女',
org: '某个公司',
des: '来自安全应急UED的设计师来自安全应急UED的设计',
},
{
id: 2,
name: 'xxx',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
},
{
id: 3,
name: '王xx',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
},
]);
const cols = ref([
{ title: '#', prop: 'id', expand: { slotName: 'index', hideLabel: true } },
{ title: '用户名', prop: 'name', slotName: 'name', expand: { slotName: 'nameExpand' } },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{
title: '简介',
prop: 'des',
showTooltip: true,
width: '40%',
expand: { slotName: 'des' },
tooltipProps: { width: '200px', popperClass: 'test-tip' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const expand = (row: { id: number }) => {
tableRef.value.toggleExpand(row.id, 'nameExpand');
};
</script>
Tree Data and Lazy Loading
Supports the display of tree-type data. When a row contains the children
field, it is treated as tree data. When rendering tree data, row-key
must be specified. Supports asynchronous loading of child node data. Set the Table's loading function load
. Specify which rows contain child nodes by specifying the hasChildren
field in the row. Both children
and hasChildren
can be configured through tree-props
. The first-column-index
prop is used to set the column on which the expand behavior acts.
ID | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
ID | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
When the children
field has an array value, the hasChildren
field will be ignored. When you need to load data asynchronously, be sure to carefully set the default-expand-all
property to true
.
<template>
<epp-simple-table :cols="cols" :data="tableData" :load="load" :expand-row-keys="['1']">
<template #tableIndex="{ row }">
<span>{{ row.id }}</span>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
<br /><br />
<epp-simple-table :cols="cols" :data="tableData" :load="load" :expand-row-keys="['1']" :first-column-index="1">
<template #tableIndex="{ row }">
<span>{{ row.id }}</span>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { isClient } from '@vueuse/core';
let count = 10000;
const tableData = ref();
const cols = ref([
{ title: 'ID', slotName: 'tableIndex' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org' },
{ title: '简介', prop: 'des', width: '220px', showTooltip: true },
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const load = (_: Record<string, any>, __: Record<string, any>, resolve: (data: Record<string, any>[]) => void) => {
window.setTimeout(() => {
resolve([
{
id: count++,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市哦!',
hasChildren: true,
},
{
id: count++,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
children: [
{
id: count++,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
],
},
]);
}, 3000);
};
if (isClient) {
window.setTimeout(() => {
tableData.value = [
{
id: 1,
name: '王二麻子',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市啊!',
children: [
{
id: 11,
name: '王二麻子11',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
children: [
{
id: 111,
name: '王二麻子111',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
{
id: 112,
name: '王二麻子112',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
},
],
},
{
id: 12,
name: '王二麻子12',
sex: '男',
org: '某个公司',
des: '来自中国南方的温暖城市!',
children: [],
},
],
},
{
id: 2,
name: '李四',
sex: '男',
org: '某个公司',
des: '来自中国',
hasChildren: true,
},
{
id: 3,
name: '张三',
sex: '男',
org: '某个公司',
des: '来自中国北方的寒冷的城市!',
},
];
}, 100);
}
</script>
Merge Rows or Columns
When multiple rows or columns share the same data, you can merge rows or columns.
id | 用户名 | Amount1 | Amount2 | Amount3 |
---|---|---|---|---|
12987122 | 234 | 3.2 | 10 | |
12987123 | Tom | 165 | 4.43 | 12 |
12987124 | 324 | 1.9 | 9 | |
12987125 | Tom | 621 | 2.2 | 17 |
12987126 | 539 | 4.1 | 15 |
id | 用户名 | Amount1 | Amount2 | Amount3 |
---|---|---|---|---|
12987122 | Tom | 234 | 3.2 | 10 |
Tom | 165 | 4.43 | 12 | |
12987124 | Tom | 324 | 1.9 | 9 |
Tom | 621 | 2.2 | 17 | |
12987126 | Tom | 539 | 4.1 | 15 |
By passing the span-method
function to the table, you can merge rows or columns. The function's parameter is an object containing four properties: row
(current row), column
(current column), rowIndex
(current row index), and columnIndex
(current column index). The function can return an array containing two elements: the first element represents rowspan
, and the second represents colspan
. You can also return an object with keys named rowspan
and colspan
.
<template>
<epp-simple-table :cols="cols" :data="tableData" border="bordered" :span-method="arraySpanMethod" />
<epp-simple-table :cols="cols" :data="tableData" border="bordered" class="m-t-md" :span-method="objectSpanMethod" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: '12987122',
name: 'Tom',
amount1: '234',
amount2: '3.2',
amount3: 10,
},
{
id: '12987123',
name: 'Tom',
amount1: '165',
amount2: '4.43',
amount3: 12,
},
{
id: '12987124',
name: 'Tom',
amount1: '324',
amount2: '1.9',
amount3: 9,
},
{
id: '12987125',
name: 'Tom',
amount1: '621',
amount2: '2.2',
amount3: 17,
},
{
id: '12987126',
name: 'Tom',
amount1: '539',
amount2: '4.1',
amount3: 15,
},
]);
const cols = ref([
{ title: 'id', prop: 'id' },
{ title: '用户名', prop: 'name' },
{ title: 'Amount1', prop: 'amount1' },
{ title: 'Amount2', prop: 'amount2' },
{ title: 'Amount3', prop: 'amount3' },
]);
const arraySpanMethod = ({ rowIndex, columnIndex }: { rowIndex: number; columnIndex: number }) => {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
};
const objectSpanMethod = ({ rowIndex, columnIndex }: { rowIndex: number; columnIndex: number }) => {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
};
</script>
Multi-level Header
When the data structure is complex, you can use a multi-level header to display the hierarchical relationship of the data.
日期 | 配送信息 | ||||
---|---|---|---|---|---|
姓名 | 地址信息 | ||||
省/市 | 城市 | 地址 | 操作 | ||
2016-05-03 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-02 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-04 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-01 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-08 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-06 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles | |
2016-05-07 | Tom | California | Los Angeles | No. 189, Grove St, Los Angeles |
Multi-level headers are implemented by nesting the children
property of cols
.
<template>
<epp-simple-table :cols="cols" :data="tableData" border="bordered">
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
date: '2016-05-03',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-02',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-04',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-01',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-08',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-06',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
{
date: '2016-05-07',
name: 'Tom',
state: 'California',
city: 'Los Angeles',
address: 'No. 189, Grove St, Los Angeles',
zip: 'CA 90036',
},
]);
const cols = ref([
{ title: '日期', prop: 'date' },
{
title: '配送信息',
prop: 'delivery',
children: [
{ title: '姓名', prop: 'name' },
{
title: '地址信息',
prop: 'address',
children: [
{ title: '省/市', prop: 'state' },
{ title: '城市', prop: 'city' },
{ title: '地址', prop: 'address' },
{ title: '操作', prop: 'zip', slotName: 'handle' },
],
},
],
},
]);
</script>
Table Footer Summation Row
If the table displays various numbers, you can display the sum of each column in the table footer.
id | 用户名 | Amount1 | Amount2 | Amount3 |
---|---|---|---|---|
12987122 | Tom | 234 | 3.2 | 10 |
12987123 | Tom | 165 | 4.43 | 12 |
12987124 | Tom | 324 | 1.9 | 9 |
12987125 | Tom | 621 | 2.2 | 17 |
12987126 | Tom | 539 | 4.1 | 15 |
合计 | ¥3232 | ¥1212.22 | ¥90.22 |
This can be implemented by customizing the foot
slot.
<template>
<epp-simple-table :cols="cols" :data="tableData" border="bordered">
<template #foot>
<tr>
<td colspan="2"><strong>合计</strong></td>
<td>¥3232</td>
<td>¥1212.22</td>
<td>¥90.22</td>
</tr>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([
{
id: '12987122',
name: 'Tom',
amount1: '234',
amount2: '3.2',
amount3: 10,
},
{
id: '12987123',
name: 'Tom',
amount1: '165',
amount2: '4.43',
amount3: 12,
},
{
id: '12987124',
name: 'Tom',
amount1: '324',
amount2: '1.9',
amount3: 9,
},
{
id: '12987125',
name: 'Tom',
amount1: '621',
amount2: '2.2',
amount3: 17,
},
{
id: '12987126',
name: 'Tom',
amount1: '539',
amount2: '4.1',
amount3: 15,
},
]);
const cols = ref([
{ title: 'id', prop: 'id' },
{ title: '用户名', prop: 'name' },
{ title: 'Amount1', prop: 'amount1' },
{ title: 'Amount2', prop: 'amount2' },
{ title: 'Amount3', prop: 'amount3' },
]);
</script>
Hide Columns
The toggleColumn
method supports hiding or showing columns.
# | 用户名 | 性别 | 单位 | 简介 | 操作 |
---|---|---|---|---|---|
1 | 范xxx | 女 | 某个公司 | 来自安全应急UED的设计师来自安全应急 | |
2 | xxx | 男 | 某个公司 | 经验丰富的前端工程师 | |
3 | 王xxxxx | 男 | 某个公司 | 90后交互设计师 |
This feature does not currently support multi-level headers or tables with merged cells.
<template>
<epp-simple-table ref="simpleTableRef" :cols="cols" :data="tableData">
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
<br /><br />
<el-button type="primary" @click="toggleColumn">隐藏/显示第3列</el-button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const simpleTableRef = ref();
const tableData = ref([
{
id: 1,
name: '范xxx',
sex: '女',
org: '某个公司',
des: '来自安全应急UED的设计师来自安全应急',
},
{
id: 2,
name: 'xxx',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
},
{
id: 3,
name: '王xxxxx',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
},
]);
const cols = ref([
{ title: '#', prop: 'id' },
{ title: '用户名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '单位', prop: 'org', align: 'center' },
{
title: '简介',
prop: 'des',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const toggleColumn = () => {
simpleTableRef.value.toggleColumn(2);
};
</script>
Drag and Drop Sorting
Use Sortablejs to implement drag and drop functionality for reordering rows in a table.
用户名 | 年龄 | 单位 | 简介 | 操作 | |
---|---|---|---|---|---|
柏庐 | 20 | 某个公司 | 来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计 | ||
军结 | 22 | 某个公司 | 经验丰富的前端工程师 | ||
钞洋 | 28 | 某个公司 | 90后交互设计师 | ||
钞洋1 | 28 | 某个公司 | 90后交互设计师 | ||
钞洋2 | 28 | 某个公司 | 90后交互设计师 |
Example Code
<template>
<epp-simple-table
:cols="cols"
:data="tableData"
class="sortable-table"
@row-click="rowClicked"
@cell-click="cellClicked"
>
<template #firstCol>
<el-checkbox v-model="selectedAll" :indeterminate="isIndeterminate" @change="selectAll" />
</template>
<template #tableIndex="{ row }">
<el-checkbox v-model="selectedRows" :value="row.id" @change="selectRow(row.id)">{{ '' }}</el-checkbox>
</template>
<template #handle>
<a>修改</a>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { isClient } from '@vueuse/core';
import Sortable from 'sortablejs';
import type { ColumnType } from 'element-plus-plus';
const selectedAll = ref(false);
const selectedRows = ref<number[]>([]);
const isIndeterminate = ref(false);
const tableData = ref([
{
id: 1,
name: '柏庐',
sex: '女',
org: '某个公司',
des: '来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计来自UED的设计师来自UED的设计',
otherInfo: {
age: 20,
},
},
{
id: 2,
name: '军结',
sex: '男',
org: '某个公司',
des: '经验丰富的前端工程师',
otherInfo: {
age: 22,
},
},
{
id: 3,
name: '钞洋',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
otherInfo: {
age: 28,
},
},
{
id: 4,
name: '钞洋1',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
otherInfo: {
age: 28,
},
},
{
id: 5,
name: '钞洋2',
sex: '男',
org: '某个公司',
des: '90后交互设计师',
otherInfo: {
age: 28,
},
},
]);
const cols = ref([
{ title: '#', slotName: 'tableIndex', headerSlotName: 'firstCol', width: '3em' },
{ title: '用户名', prop: 'name' },
{ title: '年龄', prop: 'otherInfo.age' },
{ title: '单位', prop: 'org', align: 'center' },
{
title: '简介',
prop: 'des',
align: 'center',
showTooltip: true,
width: '40%',
tooltipProps: { width: '200px', popperClass: 'test-tip' },
},
{ title: '操作', slotName: 'handle', align: 'center' },
]);
const selectAll = () => {
if (selectedAll.value) {
selectedRows.value.splice(0, selectedRows.value.length);
selectedRows.value.push(...tableData.value.map((d) => d.id));
isIndeterminate.value = false;
} else {
selectedRows.value.splice(0, selectedRows.value.length);
}
};
const selectRow = () => {
selectedAll.value = selectedRows.value.length === tableData.value.length;
if (selectedRows.value.length > 0 && selectedAll.value == false) {
isIndeterminate.value = true;
} else {
isIndeterminate.value = false;
}
};
const rowClicked = (row: Record<string, any>, rowIndex: number, event: Event) => {
console.log('rowClicked', row, rowIndex, event);
};
const cellClicked = (row: Record<string, any>, col: ColumnType, rowIndex: number, colIndex: number, event: Event) => {
console.log('cellClicked', row, col, rowIndex, colIndex, event);
};
onMounted(() => {
if (!isClient) return;
const el = document.querySelector('.sortable-table > tbody');
Sortable.create(el, {
disabled: false,
handle: 'tr',
animation: 150,
onEnd: (e: any) => {
const arr = tableData.value;
arr.splice(e.newIndex, 0, arr.splice(e.oldIndex, 1)[0]);
nextTick(() => {
tableData.value = arr;
});
},
});
});
</script>
Empty Data
序号 | 姓名 | 性别 | 操作 |
---|---|---|---|
No Data |
Example Code
<template>
<epp-simple-table :cols="cols" border="border-x" :data="tableData" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref([]);
// 序号 slot名称唯一 tableIndex。 width: 设置宽度。align: 对齐方式。showTooltip: td是否一行显示,超出tooptip
const cols = ref([
{ title: '序号', prop: '', slotName: 'tableIndex' },
{ title: '姓名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '操作', prop: '', align: 'center' },
]);
</script>
Unknown Data
序号 | 姓名 | 性别 | 操作 |
---|---|---|---|
可能数据报错了哦~ |
You can customize the unknown
slot when the passed data is null
or undefined
.
<template>
<epp-simple-table :cols="cols" border="border-x" :data="tableData">
<template #unknown>
<p style="text-align: center">可能数据报错了哦~</p>
</template>
</epp-simple-table>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tableData = ref(null);
// 序号 slot名称唯一 tableIndex。 width: 设置宽度。align: 对齐方式。showTooltip: td是否一行显示,超出tooptip
const cols = ref([
{ title: '序号', prop: '', slotName: 'tableIndex' },
{ title: '姓名', prop: 'name' },
{ title: '性别', prop: 'sex' },
{ title: '操作', prop: '', align: 'center' },
]);
</script>
Attributes
Parameter | Description | Type | Optional Values | Default Value |
---|---|---|---|---|
row-key | The key of the row data, used to optimize SimpleTable rendering. If the identifier of the table data is not the id field, you must set this value. | string / function(row): string | - | id |
border | Sets the border style for the table | string | borderless/bordered/border-x/border-y | |
padding | Sets the padding size on both sides of the table | string | 通用尺寸标签/自定义尺寸 | |
cell-padding | Sets the padding size of the table cells (TDs) | string | 通用尺寸标签/自定义尺寸 | |
gap | Sets the row spacing of the table in list mode | string | css尺寸 | |
gap-x | Sets the horizontal row spacing of the table in list mode | string | css尺寸 | |
gap-y | Sets the vertical row spacing of the table in list mode | string | css尺寸 | |
hover | Enables row hover effect | boolean | ||
cross-hover | Enables column hover effect | boolean | ||
stripe | Enables table striping effect | boolean / string | true / false / odd / even | false |
list | Enables list style | boolean | false | |
auto-height | Makes the height of TH and TD elements auto | boolean | false | |
fixed-header | Fixes the table header | boolean | - | |
fixed-footer | Fixes the table footer | boolean | - | |
show-header | Whether to display the table header | boolean | - | true |
size | Sets the table size | string | sm / md / lg | - |
resize | Whether the column width can be changed by dragging the header | boolean | - | false |
scroll-container | When setting fixed columns, if the scrolling container is not the direct parent of the table or a Scrollbar component, this prop needs to be set to support fixed column shadow effects when scrolling | string / HTMLElement | - | - |
highlight-current-row | Whether to highlight the current row | boolean | - | false |
expand-row-keys | Default expanded rows, applicable to both row expansion and tree expansion. When expanding rows, rowKey + slotName is used as the unique identifier; when expanding trees, rowKey is used. Array values must be strings. | array | - | - |
default-expand-all | Whether to expand all rows by default. Effective when SimpleTable contains expandable rows or is a tree table | boolean | - | false |
row-class-name | Callback method for the row's className . You can also use a string to set a fixed className for all rows | function({ row, rowIndex }) / string | - | - |
row-style | Callback method for the row's style . You can also use a fixed Object to set the same Style for all rows | function({ row, rowIndex }) / object | - | - |
cell-class-name | Callback method for the cell's className . You can also use a string to set a fixed className for all cells | function({ row, column, rowIndex, columnIndex }) / string | - | - |
cell-style | Callback method for the cell's style . You can also use a fixed Object to set the same Style for all cells | function({ row, column, rowIndex, columnIndex }) / object | - | - |
header-row-class-name | Callback method for the header row's className . You can also use a string to set a fixed className for all header rows | function({ row, rowIndex }) / string | - | - |
header-row-style | Callback method for the header row's style . You can also use a fixed Object to set the same Style for all header rows | function({ row, rowIndex }) / object | - | - |
header-cell-class-name | Callback method for the header cell's className . You can also use a string to set a fixed className for all header cells | function({ row, column, rowIndex, columnIndex }) / string | - | - |
header-cell-style | Callback method for the header cell's style . You can also use a fixed Object to set the same Style for all header cells | function({ row, column, rowIndex, columnIndex }) / object | - | - |
span-method | Calculation method for merging rows or columns | function({ row, column, rowIndex, columnIndex }) | - | - |
first-column-index | The column on which the tree expansion operation acts | number | - | 0 |
tree-props | Configuration options for rendering nested data | object | - | { hasChildren: 'hasChildren', children: 'children' } |
load | Function for loading child node data. The second parameter of the function contains the node's level information | function(row, treeNode, resolve) | - | - |
cols | Column configuration, see the table below | array | - | - |
cols
Parameter | Description | Type | Optional Values | Default Value |
---|---|---|---|---|
columnKey | Column key. This value needs to be set if dynamically switching table columns. Otherwise, the column width calculation will be incorrect | string | ||
title | Table column title | string | ||
prop | Property name of the table column | string | ||
showTooltip | Whether to show a tooltip. This needs to be used in conjunction with the column's width value | boolean | false | |
tooltipProps | Tooltip properties. Refer to the Popover component documentation | object | ||
align | Horizontal alignment | string | left/center/right | left |
width | Column width | string | - | |
minWidth | Minimum column width | string | - | |
maxWidth | Maximum column width | string | - | |
fixed | Fixes the column | string / object | left / right / { position: string; distance: string; } | - |
slotName | Column slot name. The default parameters are row, column, rowIndex, columnIndex . Please refer to the examples | string | - | - |
headerSlotName | Column header slot name. The default parameter is col . Please refer to the examples | string | - | - |
sortable | Whether the column is sortable | boolean / string | true / false / 'ascending' / 'descending' | - |
filter | Column filter settings | object{ slotName: string, placement: string, popperClass: string } | - | - |
expand | Expand column settings | object{ slotName: string, hideLabel: boolean } | - | - |
children | Information about child columns (for multi-level headers) | array | - | - |
formatter | Used to format content | function(row, column, cellValue, rowIndex, columnIndex) | - | - |
Events
Event Name | Description | Callback Parameter |
---|---|---|
row-click | Triggered when a row is clicked | row, rowIndex, event |
cell-click | Triggered when a cell is clicked | row, col, rowIndex, colIndex, event |
sort-change | Triggered when the sorting changes | prop, sort |
current-change | Triggered when the current row of the table changes. If you want to highlight the current row, enable the table's highlight-current-row attribute | currentRow, oldCurrentRow |
expand | Triggered when a row is expanded or collapsed | expanded, rowkey, slotName |
tree-expand | Triggered when a tree node is expanded or collapsed | expanded, row |
Methods
Method Name | Description | Parameters |
---|---|---|
toggleExpand | Expands/collapses a row. Since each row may have multiple expansions, you need to pass the slotName of the expansion you want to toggle | rowKey, slotName |
toggleExpandTree | Expands/collapses a tree node | row |
toggleColumn | Shows/hides a column | index, show(show可选) |
setCurrentRow | Used for single-selection tables. Sets a specific row as the selected row. If this method is called without parameters, it will cancel the selection of the currently highlighted row | row |
clearTooltip | Hides the tooltip | - |
Slots
Name | Description |
---|---|
empty | Content displayed when there is no data |
unknown | Custom content displayed when the table data is null or undefined |
more | Custom content displayed during pull-down to load more |
foot | Footer content of the table |