需求
常规的后台管理系统会经常用到表格展示数据,而element自带的表格需要花很多代码编写HTML部分,为了减少编写的代码以及增加表格的可配置性,减少需求变更时代码的编写量,所以需要对表格进行二次封装。需求入下:
- 通过JS的方式配置表格的列数据,继承原本列的可配置项
- 存在一定的可扩展性,能够自定义列数据
代码
<!--表格组件-->
<template>
<div class="makeid-table">
<el-table
element-loading-text="数据加载中"
v-loading="loading"
:data="dataList"
height="100%"
border
@selection-change="selectionChange"
v-adaptive="{type:'table',bottomOffset:bottomOffset}"
:key="tableKey"
:row-key="getRowKeys"
>
<el-table-column :reserve-selection="true" align="center" v-if="isSelection" type="selection" width="55" />
<el-table-column align="center" type="index" label="序号" width="50px" />
<el-table-column align="center" v-for="item in columns" :key="item.prop" v-bind="item">
<!-- 根据实际情况传入自定义内容 -->
<template v-slot="{ row, $index }">
<slot :name="item.prop" :row="row" :index="$index">
{{ row[item.prop] }}
</slot>
</template>
</el-table-column>
</el-table>
<!-- 底部部分 -->
<div class="footer" v-if="isPagination">
<el-pagination
background
layout="total, prev, pager, next, sizes,jumper"
:total="pagination.total"
:page-size="pagination.pageSize"
:page-sizes="pagination.pageRange"
:current-page="pagination.pageNo"
@current-change="currentChange"
@size-change="sizeChange">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
props: {
tableKey: {
type: String,
default: ''
},
loading:{
type:Boolean,
default:true
},
dataList:{
type:Array,
default(){
return []
}
},
columns:{
type:Array,
default(){
return []
}
},
isSelection: {
type: Boolean,
default: false,
},
isPagination: {
type: Boolean,
default: true
},
pagination: {
type: Object,
default () {
return {
pageNo: 1,
pageSize: 10,
total: 0,
pageRange: [10, 20, 30, 50, 100],
}
}
},
currentChange:{
type:Function,
default:()=>{}
},
sizeChange:{
type:Function,
default:()=>{}
},
selectionChange:{
type:Function,
default:()=>{}
},
bottomOffset:{
type:String,
default:'60'
},
rowId:{
type:String,
default:'id'
}
},
data() { return {} },
mounted() { },
methods: {
// 跨页多选
getRowKeys(row) {
return row[this.rowId]
},
}
}
</script>
<style lang='scss' scoped>
.makeid-table{
.footer{
margin-top:10px;
}
}
讲解
实现思路
动态列实现的就是通过for循环去生成列数据,在循环生成列时,通过v-bind="item" 可以很方便的绑定外界传进来的属性用在element-column上,不需要使用prop的方式,再利用命名插槽的作用能够让用户自定义列的数据,getRowKeys的作用是实现跨页多选,具体可百度查询。
一些问题
该组件传递了很多Function,比如currentChange,sizeChange等,这是可以优化的,因为在项目中统一封装了tableMixins.js封装了这几个函数所以就统一传进来了,如果需要优化可以使用model:update的方式实pagination双向绑定就可以减少这几个函数的传入,具体实现可自行编写。因为现在项目主要是vue3,所以后续再封装vue3版本的表格组件。
v-adaptive="{type:'table',bottomOffset:bottomOffset}" 是一个自定义指令用于自适应表格高度撑满容器,不需要可自行删除,如果需要,评论区留言,后续补上。
使用
<MakeidTableBox
tableKey="DealOrder_List"
bottomOffset="85"
:loading="loading"
:dataList="dataList"
:columns="columns"
:pagination="pagination"
:currentChange="handleCurrentChange"
:sizeChange="handleSizeChange"
>
//operation 是操作列
<template #operation="{ row }">
<el-button
@click="handleDownload(row)"
class="table-icon"
type="text"
size="medium"
>
<i class="el-icon-download"></i>
<span>下载</span>
</el-button>
<el-button
class="table-icon"
@click="handleDelete(row)"
type="text"
size="medium"
>
<i class="el-icon-delete"></i>
<span>删除</span>
</el-button>
</template>
</MakeidTableBox>
// JS 部分 变量定义
loading:false,
dataList:[],
columns: [
{ label: "单据编号",prop: "invoiceCode"},
{ label: "文件名称",prop: "fileName"},
{ label: "报废单位",prop: "assetUnit"},
{ label: "备注",prop: "remark"},
{ label: "创建人", prop: "createUser", width: "160"},
{ label: "创建时间",prop: "createDate",width: "160"},
{ label: "操作",prop: "operation",width: "160"},
],
pagination: {
pageNo: 1,
pageSize: 10,
total: 0,
pageRange: [10, 20, 30, 50, 100],
},
总结
目前组件实现的还比较粗糙,不过能够覆盖业务中大部分表格使用,后续有其他需求时再优化,如果有更好的意见欢迎评论,学习一下。