最近自己基于element-ui的el-table二次封装了一个表格,直接分享代码吧
<template>
<div>
<el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
<template>
<el-table-column v-if="selection ==='multiple'" type="selection" width="55" align="center">
</el-table-column>
<el-table-column v-for="(item, index) in tableHeader"
:key="index"
:prop="item.prop"
:label="item.label"
:align="item.align">
<template v-if="item.slot" v-slot:default="scope">
<slot :name="item.prop" :row="scope.row" :index="scope.$index"></slot>
</template>
<template v-else v-slot:default="scope">
<div v-if="item.format">
{{item.format(scope.row)}}
</div>
<div v-else>
{{scope.row[item.prop]}}
</div>
</template>
</el-table-column>
<el-table-column label="操作" v-if='operate'>
<template v-slot:default="scope">
<slot name="operate" :row="scope.row" :index="scope.$index"></slot>
</template>
</el-table-column>
</template>
</el-table>
<el-pagination
v-if="hasPageNation"
:current-page.sync="pageNum"
:page-size.sync="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[10, 20, 30, 40]"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
export default{
name: 'ftable',
props: {
// 受否可以选择
selection: {
type: String,
default: 'multiple'
},
// 表头列
tableHeader: {
type: Array,
default: () => {
return []
}
},
// 是否有操作列
operate: {
type: Boolean,
default: true
},
// 是否分页
hasPageNation: {
type: Boolean,
default: true
},
// 是否自动请求
isAutoRequest: {
type: Boolean,
default: true
},
// 获取表格数据的函数
data: {
type: Function,
require: true
}
},
data() {
return {
loading: false, // 表格请求数据蒙层loading
tableData: [], // 表格数据
pageSize: 10, // 分页每页条数
pageNum: 1, // 分页当前页
total: 0, // 总页数
refreshParameter: {} // 刷新表格的请求参数
}
},
mounted() {
this.isAutoRequest && this.loadData(); // 首次是否加载表格数据
},
methods: {
// 勾选数据
handleSelectionChange(data) {
console.log(data);
},
// 加载数据方法
loadData() {
debugger
if(this.loading) {
return
}
this.loading = true;
const parameter = this.hasPageNation ? {...this.refreshParameter, pageNum: this.pageNum, pageSize: this.pageSize} : this.refreshParameter;
const result = this.data(parameter); // 调用父组件传过来的函数
console.log(result); // 一个promise对象
this.refreshParameter = {};
if((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
return result.then(
res => {
this.loading = false;
const {list, pageNum, pageSize, total} = res;
this.tableData = list || [];
this.hasPageNation && pageNum &&(this.pageNum = pageNum);
this.hasPageNation && pageSize &&(this.pageSize = pageSize);
this.hasPageNation && total !== undefined &&(this.total = total);
}
).finally(() => {
this.loading = false;
})
.catch(err => {
this.loading = false;
})
}
},
// 表格重新加载方法 param false加载第一个 true加载当前页 object重新携带参数
refresh(param = false) {
const type = typeof param;
if(type === 'boolean') {
!param && (this.pageNum = 1);
} else if(type === 'object') {
this.refreshParameter = param;
}
this.loadData();
},
// 分页每页多少条
handleSizeChange(val) {
if (this.pageNum * val > this.total) {
this.pageNum = 1;
}
this.pageNum = val;
this.refresh();
},
// 分页跳到第几页
handleCurrentChange(val) {
this.pageNum = val;
this.refresh(true);
}
}
}
</script>
使用例子:
<ftable ref="ftable" :data="loadData" :tableHeader="tableHeader">
<template v-slot:ipaddr="scope">
<span style="color: red;">{{scope.row.ipaddr}}</span>
</template>
<template v-slot:loginLocation="scope">
<span style="color: green;">{{scope.row.loginLocation}}</span>
</template>
<template v-slot:operate="scope">
<el-button type="text">编辑</el-button>
</template>
</ftable>
<script>
import Ftable from "@/views/components/myComponents/table"
import { list } from "@/api/monitor/logininfor";
export default {
name: "index",
components: {Ftable},
dicts: ['sys_common_status'],
data() {
return{
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
ipaddr: undefined,
userName: undefined,
status: undefined
},
dateRange: [],
// 表头列
tableHeader: [
{prop: 'infoId', label: '访问编号', align: 'center'},
{prop: 'userName', label: '用户名称', align: 'center'},
{prop: 'ipaddr', label: '登录地址', align: 'center', slot: true},
{prop: 'loginLocation', label: '登录地点', align: 'center',slot: true},
{prop: 'browser', label: '浏览完', align: 'center'},
{prop: 'os', label: '操作系统', align: 'center'},
{prop: 'status', label: '登录状态', align: 'center',
format: (row) => {
let statusShow = row.status === '0' ? '在线' : '离线';
return statusShow;
}
}
]
}
},
methods: {
loadData(parameter) {
console.log(parameter);
let data = {
...this.queryParams,
dateRange: this.dateRange,
pageSize: parameter.pageSize,
pageNum: parameter.pageNum
}
console.log(data);
return list(data).then(res => {
console.log(res);
return {
list: res.rows || [],
pageNum: data.pageNum,
pageSize: data.pageSize,
total: res.total
}
})
},
/** 搜索按钮操作 */
handleQuery() {
this.$refs.ftable.refresh(); // 请求第一页
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
},
}
}
</script>
最终效果: