谈谈element的table组件二次封装,之前也封装过一次,但真的太差了,所以再重新封装一次,记录一下。如有错误恳请指正
主要包括了以下几个功能
- 表格分页
- 筛选列
- 查询
表格
参数内容
参数 | 说明 | 默认值,类型 |
---|---|---|
tableData | 表格数据 | [] |
columnList | 列数据 | [] |
tableName | ref属性 | string |
showExpand | 展示详细信息 | false,boolean |
allowSelect | 允许多选 | false,boolean |
showSort | 展示序号 | true,boolean |
hasOption | 是否有操作 | true,boolean |
total | 数据总数 | 1,number |
column参数
参数 | 说明 | |
---|---|---|
label | 标签名 | |
prop | 对应字段名 | |
filter | 筛选 | |
formatter | 格式转换 | |
child | 复合表格 |
方法说明
方法名称 | 说明 | 参数 |
---|---|---|
filter-change | 表头筛选 | data,[] |
page-change | 页码选择 | {type:('page','size'),value} |
select-all | 全选按钮 | data |
select-one | 单选一条数据 | data |
// Table组件
<el-table
:data="tableData" // 表单数据
@filter-change="filterChangeMethod" // 表头下拉筛选
:hide-on-single-page="true"
:ref="tableName"
border
@select-all="selectAllMethod" // 表头全选按钮
@select="selectOneMethod" // 选择单条数据
style="width: 100%; margin-top:20px;">
</el-table>
showExpand
// Table组件
<el-table-column v-if="showExpand" type='expand'>
<template #default="scope"> // 原有element设置的
<slot name="expand" :scope="scope"></slot> // 自定义内容插槽
</template>
</el-table-column>
// 用法
<template #expand="{ scope }">
<div>
测试123123{{scope.row.age}}
</div>
</template>
allowSelect
// Table组件
<el-table-column
v-if="allowSelect"
type='selection'>
</el-table-column>
<script>
// 对应选择操作
// 全选操作
const selectAllMethod = (data) => {
emit('select-all', data);
};
// 单选操作
const selectOneMethod = (data) => {
emit('select-one', data);
};
</script>
showSort
// Table组件
<el-table-column
v-if="showSort"
type='index'
label="序号"
:index="count"
width="50%">
</el-table-column>
<script>
// 序号排序功能(序号连续性)
const count = (index) => (state.tempPage - 1) * state.tempPageSize + index + 1;
</script>
hasOption
// Table组件
<el-table-column
fixed="right"
label="操作"
v-if="hasOption">
<template #default="scope">
<slot :scope="scope" name="option"></slot>
</template>
</el-table-column>
// 用法
<template #option="{ scope }">
<el-button @click="detail(scope)">详情</el-button>
</template>
内容显示(多级表头的设置)
// Table组件
<CColumn
:contentData="item"
v-for="(item,index) in columnListResult"
:key="index">
<template #content="{data}">
<slot :scope="data" :name="item.prop"></slot>
</template>
</CColumn>
// Column组件
没有子列表
<el-table-column
:label="contentData.label"
:filters="contentData.filter"
:column-key="contentData.prop"
filter-placement="bottom-end"
:filter-multiple="false"
:formatter="contentData.formatter"
v-if="!contentData.child">
// v-if="!contentData.formatter" 如果属性设置formatter直接走element原有的formatter设置
<template #default="scope" v-if="!contentData.formatter">// element自定义行显示内容
<slot :data="scope" name="content">
{{scope.row[contentData.prop] || '--'}}
</slot>
</template>
</el-table-column>
<el-table-column
:label="contentData.label"
:filters="contentData.filter"
:column-key="contentData.prop"
filter-placement="bottom-end"
:filter-multiple="false"
:formatter="contentData.formatter"
v-if="contentData.child">
<CColumn :contentData="item" v-for="(item,index) in contentData.child" :key="index" />// 递归展示内容
</el-table-column>
// 内容自定义用法
<template #status="{ scope }">// slot的name是prop的值
<el-button v-if="scope.row.status === 1">在职</el-button>
<el-button v-if="scope.row.status === 0">离职</el-button>
</template>
// 列属性
[{
label: 'SUM',
child: [
{
label: 'NAME',
prop: 'name',
},
],
},
{
label: 'AGE',
prop: 'age',
formatter: (scope) => scope.age + 2,
},
{
label: 'STATUS',
prop: 'status',
filter: [
{ text: 'ON', value: 'on' },
{ text: 'OFF', value: 'off' },
],
},]
分页设置
用的还是element的分页组件
// Page组件
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
:current-page="currPage"
:page-size="currPageSize"
:page-sizes="pageSizes"
@current-change="handleCurrentChange"
@size-change="handleSizeChange">
</el-pagination>
<script>
// 把页数、数量放在同一个函数里面判断执行
const handleCurrentChange = (value) => {
emit('page-change', { type: 'page', value });
};
const handleSizeChange = (value) => {
emit('page-change', { type: 'size', value });
};
</script>
// Table组件
<CPage
@page-change="pageChangeMethod"
v-if="showPage">
</CPage>
<script>
// 分页选择
const pageChangeMethod = (data) => {
const { type, value } = data;
if (type === 'page') {
state.tempPage = value;
}
if (type === 'size') {
state.tempPageSize = value;
}
emit('page-change', data);
};
</script>