在做项目的时候特别是后台管理的时候table难免用的多,所有根据vue框架对table进行二次封装
好处那就是可以省很多代码,而且用起来也方便。非常的奈斯
<div class="hs-table">
<el-table
:class="comFooterShow ? 'singleTable' : 'notFooterTable'"
ref="singleTable"
:highlight-current-row="selectCurRow"
@current-change="handleCurChange"
:data="dataProcessing()"
stripe
:max-height="maxHeight"
:show-header="showHeader"
:size="size"
:row-key="getKey"
@selection-change="selectionChange"
>
<!-- 自定义表格首列显示内容 -->
<slot name="firstCustom"></slot>
<el-table-column
v-if="selectionShow"
align="center"
type="selection"
width="45"
:reserve-selection="true"
>
</el-table-column>
<el-table-column v-if="expandShow" type="expand" width="30">
<template slot-scope="props">
<div class="flex-jc-flex-end">
<div class="work-order-spli">
<slot name="expand" :props="props"></slot>
</div>
</div>
</template>
</el-table-column>
<template v-for="(item, index) in tableHead">
<el-table-column
v-if="item.time"
:label="item.column_comment"
:key="index + item.column_comment"
:show-overflow-tooltip="item.showTooltip ? item.showTooltip : false"
:width="item.width"
:sortable="item.sortable"
:sort-method="(a, b) => sortTimeFun(a, b, item.column_name)"
:prop="item.column_name"
>
<template slot-scope="scope">
<div>{{ setTime(scope.row, item.column_name) }}</div>
</template>
</el-table-column>
<template v-else-if="item.custom">
<slot name="custom" :index="index" :item="item"></slot>
</template>
<el-table-column
v-else
:prop="item.column_name"
:label="item.column_comment"
:key="index + item.column_name"
:show-overflow-tooltip="item.showTooltip ? item.showTooltip : false"
:width="item.width"
:sortable="item.sortable"
></el-table-column>
</template>
<template v-if="defaultBtn">
<el-table-column width="80" align="center" label="操作">
<template slot-scope="scope">
<el-popover
v-model="scope.row.popoverShow"
placement="bottom"
trigger="click"
>
<div style="padding: 8px">
<el-button
v-if="editShow"
size="mini"
icon="el-icon-edit"
type="primary"
:disabled="disabled"
@click="handleEdit(scope.$index, scope.row)"
>编辑</el-button
>
<el-button
v-if="deleteShow"
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
icon="el-icon-delete"
:disabled="disabled"
>删除</el-button
>
<slot name="otherBtn" :scope="scope"></slot>
</div>
<el-button
class="button-no-border"
size="mini"
icon="el-icon-more"
slot="reference"
></el-button>
</el-popover>
</template>
</el-table-column>
</template>
</el-table>
<div
v-if="comFooterShow"
class="flex-jc-space-between-d"
style="margin: 20px 0px 0px"
>
<div class="flex-jc-flex-start">
<template v-if="allSelectShow">
<el-checkbox
:disabled="!dataProcessing().length"
:indeterminate="isCheckbox"
@change="toggleAllSelect"
size="small"
v-model="selectAll"
>全选</el-checkbox
>
<slot name="batchOperation" :selectData="selectData"></slot>
</template>
</div>
<div
class="paginationBox"
v-if="paginationShow"
style="text-align: right"
>
<el-pagination
class="pagination"
background
layout="total, sizes, prev, pager, next"
:hide-on-single-page="tableSetting.paginationDis"
:small="tableSetting.smallPage"
:pager-count="tableSetting.pagerCount"
:total="totalData"
:current-page="tableSetting.currentPage"
@current-change="handelCurChange"
@prev-click="handelCurChange"
@next-click="handelCurChange"
:page-size="tableSetting.pageSize"
:page-sizes="[1, 20, 50, 100, 500]"
@size-change="handleSizeChange"
></el-pagination>
</div>
</div>
</div>
props: {
disabled: {
type: Boolean,
default: false,
},
showHeader: {
type: Boolean,
default: true,
},
selectionShow: {
// 多选框
type: Boolean,
default: false,
},
expandShow: {
// 表格可展开 false默认不可以 true可以
type: Boolean,
default: false,
},
defaultBtn: {
// 显示操作列(默认按钮),如果设置false则不显示
type: Boolean,
default: true,
},
allSelectShow: {
// 显示全选按钮,默认不显示
type: Boolean,
default: false,
},
paginationShow: {
// 显示默认按钮,如果设置false则可以自定义
type: Boolean,
default: true,
},
editShow: {
// 编辑按钮显示
type: Boolean,
default: true,
},
deleteShow: {
// 删除按钮显示
type: Boolean,
default: true,
},
selectCurRow: {
// 当前可选择
type: Boolean,
default: true,
},
maxHeight: {
// 固定高度
type: [Number, String],
default: "100vh",
},
fontSize: {
// 表格字体大小
type: String,
default: "24px",
},
size: {
// 表格大小控制
type: String,
default: null,
},
tableHead: {
// 表头数据
type: Array,
default: function () {
return [];
},
},
tableData: {
// 表格数据
type: Array,
default: function () {
return [];
},
},
pageFlag: {
// 后端分页(或显示全部都显示为true) 开启后必须使用total字段 false=>前端分页
type: Boolean,
default: false,
},
total: {
// 数据总数 pageFlag:true 才生效
type: Number,
default: 0,
},
},
data() {
return {
tableSetting: {
total: 0, // 总数
currentPage: 1, // 当前页
pageSize: 20, // 每页显示数量
paginationDis: false, // 1个分页则隐藏分页标签
smallPage: false, // 小型分页样式
pagerCount: 5, //页码按钮的数量,当总页数超过该值时会折叠
},
selectAll: false,
isCheckbox: false,
selectData: [],
};
},
computed: {
comFooterShow() {
return this.allSelectShow || this.paginationShow;
},
totalData() {
if (this.pageFlag) {
return this.total;
} else {
return this.tableData.length;
}
},
},
methods: {
initTableSetting() {
let that = this;
that.tableSetting = {
total: 0, // 总数
currentPage: 1, // 当前页
pageSize: 20, // 每页显示数量
paginationDis: false, // 1个分页则隐藏分页标签
smallPage: false, // 小型分页样式
pagerCount: 5, //页码按钮的数量,当总页数超过该值时会折叠
};
},
handelCurChange(page) {
// 改变当前页
console.log("改变当前页", page);
let that = this;
that.tableSetting.currentPage = page;
that.$emit("change-page", that.tableSetting);
},
handleSizeChange(val) {
// 选择显示数据量
console.log(`每页 ${val} 条`);
console.log(val);
let that = this;
that.tableSetting.pageSize = val;
that.tableSetting.currentPage = 1;
that.$emit("change-page", that.tableSetting);
},
toggleAllSelect(val) {
let that = this;
console.log("toggleAllSelect", val);
if (val) {
that.$refs.singleTable.toggleAllSelection();
} else {
that.$refs.singleTable.clearSelection();
}
that.isCheckbox = false;
},
selectionChange(val) {
console.log("selectionChange", val);
let that = this;
that.selectData = val;
let checkedCount = val && val.length ? val.length : 0;
that.selectAll = checkedCount === that.tableData.length;
that.isCheckbox =
checkedCount > 0 && checkedCount < that.tableData.length;
that.$emit("select-data", that.selectData);
},
handleCurChange(val) {
// 选择当前行
let that = this;
// console.log("选择当前行", val);
that.$emit("select-current", val);
},
setCurrent(row) {
let that = this;
// 选择表格第几行
that.$refs.singleTable.setCurrentRow(row);
console.log("选择表格第几行", row);
},
handleDelete(index, val) {
// 删除按钮事件
let that = this;
console.log("删除", val);
val.popoverShow = false;
that.$emit("handle-delete", val);
},
handleEdit(index, val) {
// 编辑按钮事件
// console.log("编辑", val);
let that = this;
val.popoverShow = false;
that.$emit("handle-edit", val);
},
getKey(row) {
return row.Id;
},
dataProcessing() {
// 分页功能
let that = this;
let data = [];
if (that.pageFlag) {
data = that.tableData;
} else {
let pageSize = that.tableSetting.pageSize;
let currentPage = that.tableSetting.currentPage;
data = that.tableData.slice(
(currentPage - 1) * pageSize,
currentPage * pageSize
);
}
return data;
},
sortTimeFun(a, b, columnName) {
let nameArr = columnName.split("."); // 通过.截取处理每一层的key
let dataA = JSON.parse(JSON.stringify(a));
let dataB = JSON.parse(JSON.stringify(b));
nameArr.forEach((item) => {
// 遍历拿到最后的值
dataA = dataA[item];
dataB = dataB[item];
});
return Date.parse(dataA) - Date.parse(dataB);
},
setTime(val, name) {
let nameArr = name.split(".");
// console.log(val, nameArr);
let data = val;
nameArr.forEach((item) => {
data = data[item];
});
// console.log(data);
if (data) {
return SysGlobal.formatDateTime(data);
}
},
},
<style scoped lang="scss">
.hs-table::v-deep {
height: 100%;
.paginationBox {
height: 32px;
}
.el-table.singleTable {
height: calc(100% - 53px);
display: flex;
flex-direction: column;
.el-table__header-wrapper {
flex: none;
}
.el-table__body-wrapper {
flex: auto;
overflow: auto;
}
.cell {
height: 100%;
line-height: normal;
}
}
.el-table.notFooterTable {
height: 100%;
display: flex;
flex-direction: column;
.el-table__header-wrapper {
flex: none;
}
.el-table__body-wrapper {
flex: auto;
overflow: auto;
}
.cell {
height: 100%;
line-height: normal;
}
}
}
.work-order-spli {
width: calc(100% - 95px);
}
.color-box-flex {
display: flex;
justify-content: flex-start;
}
.doc-lock {
padding: 4px 4px;
font-size: 18px;
border-radius: 4px;
cursor: pointer;
}
.doc-lock:hover {
background-color: white;
}
</style>
<el-card>
<Table
:default-btn="true"
:edit-show="true"
:pageFlag="true"
:selectionShow="true"
:table-head="tableData.header"
:table-data="tableData.list"
:total="tableSetting.Total"
@handle-delete="handleDelete"
@handle-edit="handleEdit"
@select-data="currentSelectChange"
@change-page="changePage"
>
<!-- 通过custom方法可以去对table里面某些字段进行特殊处理 -->
<template slot="custom" v-if="item.custom" slot-scope="{ item, index }">
<el-table-column
:prop="item.column_name"
:label="item.column_comment"
:key="index + item.column_name"
:show-overflow-tooltip="item.showTooltip ? item.showTooltip : false"
:width="item.width"
:sortable="item.sortable"
>
<template slot-scope="scope">
<span v-if="item.column_name == 'DeviceTypeUid'">
{{ formatDeviceType(scope.row) }}
</span>
<span v-else-if="item.column_name == 'DeviceGroupUid'">
{{ formatDmpDeviceType(scope.row) }}</span
>
</template>
</el-table-column>
</template>
<!-- 可以在当前页面添加特殊按钮的时候可以这么添加 -->
<template slot="otherBtn" slot-scope="{ scope }">
<el-button
size="mini"
icon="hs hs-web-authority-assignment"
type="primary"
@click="handleJurisdiction(scope.$index, scope.row)"
:disabled="scope.row.UpdateFlag === 0 ? true : false"
>
分配權限</el-button
>
</template>
</Table>
</el-card>
data() {
return {
tableData: {
loading: false,
header: [
{
id: 1,
column_name: "name",
column_comment: "姓名",
showTooltip: false,
},
{
id: 2,
column_name: "Code",
column_comment: "编号",
showTooltip: false,
sortable: true,
},
{
id: 3,
column_name: "DeviceTypeUid",
column_comment: "设备1",
showTooltip: false,
sortable: true, //开启排序
custom: true,//当custom为true 时就会触发上面那个判断
},
{
id: 4,
column_name: "DeviceGroupUid",
column_comment: "设备2",
showTooltip: false,
sortable: true,
custom: true,
},
],
list: [
{
id: 1,
name: "test",
Code: "1",
DeviceTypeUid: "1",
DeviceGroupUid: "1",
},
{
id: 2,
name: "test2",
Code: "2",
DeviceTypeUid: "2",
DeviceGroupUid: "2",
},
{
id: 3,
name: "test3",
Code: "3",
DeviceTypeUid: "3",
DeviceGroupUid: "3",
},
],
},
deviceList: [
{
name: "设备1",
id: "1",
},
{
name: "设备2",
id: "2",
},
{
name: "设备3",
id: "3",
},
],
tableSetting: {
Total: 3, // 总数
PageSize: 20, // 每页显示数量
CurrentPage: 1, // 当前页
},
};
},