1、通常项目里使用表格的页面很多,每个页面如果都要写一份感觉很麻烦,所以把表格封装起来进行复用。这个表格适用于多级表头 、带有页码、行点击高亮、双击事件、复选反选等。
父组件使用:如图一所示
下面的代码就是封装的表格
<template>
<!-- 简单表格、多层表头、页码、没有合并列行 -->
<div class="maintenPublictable">
<!--cell-style 改变某一列行的背景色 -->
<!-- tree-props 配置树形子表
row-click: 某一行单击事件
highlight-current-row:高亮选中某行
default-expand-all:默认是否展开字列表
current-change:管理选中时触发的事件
selection-change:多选框
row-key="id": id:一定要跟后台返回来的id一致,不一致,会出错
show-summary: 显示合计
summary-method: 合计指定的某一列
row-dblclick: 某一行被双击
stripe :斑马纹
border
show-overflow-tooltip :当内容过长被隐藏时显示 tooltip
-->
<!-- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" -->
<el-table
class="rollTableRow"
ref="table"
stripe
:data="tableData"
:height="getHeight"
:show-summary="showSum"
:summary-method="getSummaries"
@selection-change="handleSelectionChange"
:key="itemKey"
:cell-style="tableCellStyle"
@row-click="clickRow"
@row-dblclick="rowDblclick"
row-key="ID"
:default-expand-all="defaultall"
:highlight-current-row="highlightCurrent"
@current-change="handleCurrentChangeRow"
:tree-props="{ children: 'Children' }"
header-row-class-name="headerStyle"
>
<el-table-column
type="index"
width="55"
label="序号"
>
</el-table-column>
<el-table-column
type="selection"
v-if="isSelection"
width="55"
>
</el-table-column>
<!-- item.direction 方向,判断居中还是靠右 -->
<template v-for="(item, index) in tableHeader">
<!-- 1. 这是第一层 -->
<!-- sortable: 排序 item.direction -->
<el-table-column
v-if="!item.child"
:key="index"
:prop="item.prop"
:label="item.label"
header-align="center"
:align="item.direction"
:min-width="item.width"
:sortable="item.sortable"
show-overflow-tooltip
>
</el-table-column>
<!-- 二级表头 -->
<el-table-column
v-else
:key="index + 1"
:prop="item.prop"
:label="item.label"
:type="item.type"
:align="item.align || 'center'"
>
<template v-for="(childItem, index) in item.child">
<!-- 三级表头 -->
<el-table-column
v-if="!childItem.child"
:key="index"
:prop="childItem.prop"
:label="childItem.label"
header-align="center"
:align="childItem.center"
:min-width="childItem.width"
>
</el-table-column>
<el-table-column
v-else
:key="index + 1"
:prop="childItem.prop"
:label="childItem.label"
:type="childItem.type"
:align="childItem.align || 'center'"
>
<template v-for="(childItem, index) in item.child">
<!-- 这是第三层 -->
<el-table-column
v-if="!childItem.child"
:key="index"
:prop="childItem.prop"
:label="childItem.label"
header-align="center"
:align="childItem.center"
:min-width="childItem.width"
>
</el-table-column>
<el-table-column
v-else
:key="index + 1"
:prop="childItem.prop"
:label="childItem.label"
:type="childItem.type"
:align="childItem.align || 'center'"
>
</el-table-column>
</template>
</el-table-column>
</template>
</el-table-column>
</template>
<!-- 表格最后一列是否是勾选框【完成情况】 -->
<el-table-column
v-if="isSelect"
align="center"
>
<template
slot="header"
slot-scope="scope"
>
<el-checkbox
@change="allCheck(isAllcheck, tableData, ClickIdsList, isIndeterminate)"
size="large"
v-model="isAllcheck"
:indeterminate="isIndeterminate"
></el-checkbox>完成情况
</template>
<template slot-scope="scope">
<!-- <el-button @click="Ones(scope)">122333</el-button> -->
<el-checkbox
@change="OnesClick(scope.row)"
v-model="scope.row.check"
class="ml-4"
size="large"
></el-checkbox>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div
v-if="showFenYe"
class="fenYeStyle"
>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page.currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="page.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total"
>
</el-pagination>
</div>
</div>
</template>
<script>
// import preventBack from "vue-prevent-browser-back"; //阻止返回
import { PublicFunction } from "@/utils/vuePublic";
export default {
name: "maintenPublictable",
components: {},
props: {
// 接收的是:是否有分页、是否有勾选
columns: {
type: Object,
default: {},
},
// 接收的是:页码
pagination: {
type: Object,
default: {},
},
},
data() {
return {
tableHeader: [], //表头
tableData: [], //数据
itemKey: "",
types: 1, //用于合并,判断是否需要合并
//#region 与父组件关联
getHeight: 20, //高度
isSelect: false, //勾选框
showFenYe: false, //是否有分页
isSelection: false, //是否有多选框
isTag: false, //是否有标签
defaultall: false, //是否默认展开所有行(用于有树状结构的表格)
highlightCurrent: false, //高亮选中
showSum: false, //合计
//#endregion
// 页码
page: {
currentPage: 1, //当前页
pagesize: 10, //当前页的条数
total: 20, //总数
},
//多选框
multipleSelection: [],
//#region 用于右侧的完成情况
//选择
isAllcheck: false, //全选
ClickIdsList: [], //已选择集合组
isIndeterminate: false, //部分选中,默认是false
//#endregion
};
},
// mixins: [preventBack], //注入 阻止返回上一页
created() {},
watch: {
// 监听对象的写法(监听页码的变化)
pagination: {
handler(newValue, oldVal) {
// console.log("监听111", oldVal);
// console.log("监听222", newValue);
this.page.total = newValue.total;
},
deep: true, // 深度监听
// immediate: true, //写上它,初始化时也会调用监听
},
},
mounted() {
this.init();
// console.log(this.columns, "初始化:接收父组件传过来的值", this.pagination);
},
methods: {
Ones(value) {
console.log("12121212", value);
},
//在父组件初始化时,需要获得页码,所以子组件初始化时把页码传过去
init() {
let _this = this;
_this.getHeight = this.columns.getHeight;
_this.showSum = this.columns.showSum; //合计
_this.defaultall = this.columns.defaultall; //是否展开所有行
_this.isSelect = this.columns.isSelect; //右侧的完成情况
_this.isTag = this.columns.isTag; //是否有标签
_this.showFenYe = this.columns.showFenYe;
_this.isSelection = this.columns.isSelection; //左侧的多选框
_this.highlightCurrent = this.columns.highlightCurrent; //高亮选中
_this.page.total = this.pagination.total;
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 1,
},
});
},
//一页有多少条数据
handleSizeChange(val) {
let _this = this;
_this.page.pagesize = val;
// 子传父
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 2,
},
});
},
//第几页/切换页码
handleCurrentChange(val) {
let _this = this;
_this.page.currentPage = val;
_this.$emit("getPage", {
data: {
pageSize: _this.page.pagesize,
pageNum: _this.page.currentPage,
isTypes: 2,
},
});
},
//表头
SetDataTableHeader(GetDataLists) {
//重新渲染,itemKey用于处理Table不渲染的问题
this.itemKey = Math.random();
//重新渲染数据表
this.tableHeader = GetDataLists;
// console.log("表头", this.tableHeader);
// this.$forceUpdate()
},
//table值
SettableData(tabledata) {
console.log(tabledata, "tabledata");
let _this = this;
_this.tableData = tabledata;
// console.log("接收父组件传过来的表格数据", tabledata);
},
//左侧:多选框
handleSelectionChange(val) {
this.multipleSelection = val;
// console.log("左侧:勾选数据", this.multipleSelection);
this.$emit("handleSelectionChange", val);
},
//#region 下面这个是用于最右侧的完成情况
//全选 调取公共js文件的方法
allCheck(isAll, tableData, checkList, isCheck) {
//接收传过来的值
let objData = PublicFunction.allCheck(
isAll,
tableData,
checkList,
isCheck
);
this.isAllcheck = objData.isAll;
this.ClickIdsList = objData.checkList;
},
//单行选择
OnesClick(rows) {
if (rows.check) {
this.ClickIdsList.push(rows.id);
} else {
let index = this.ClickIdsList.indexOf(rows.id);
this.ClickIdsList.splice(index, 1);
}
// console.log("勾选111", this.ClickIdsList);
this.isIndeterminate =
this.ClickIdsList.length > 0 &&
this.ClickIdsList.length < this.tableData.length;
this.isAllcheck = this.ClickIdsList.length == this.tableData.length;
},
//#endregion
// 合并单元格
objectSpanMethod({ row, column, rowIndex, columnIndex }, tableData, types) {
if (types === 1) {
switch (
columnIndex // 将列索引作为判断值
) {
// 通过传递不同的列索引和需要合并的属性名,可以实现不同列的合并(索引0,1 指的是页面上的0,1)
case 2:
return PublicFunction.MergeCol(tableData, "itemDetail", rowIndex);
case 1:
return PublicFunction.MergeCol(tableData, "item", rowIndex);
}
} else {
//保障作业
switch (columnIndex) {
case 1:
return PublicFunction.MergeCol(tableData, "item", rowIndex);
}
}
},
// 提交(在父组件点击提交时调用这个方法)
childSumbit() {
let param = {
tabledata: this.tableData,
ClickIdsList: this.ClickIdsList,
multipleSelection: this.multipleSelection,
};
// 把值传给父组件
this.$emit("sumbitData", param);
},
//行点击事件
clickRow(row, column, event) {
this.$emit("rowClick", row);
},
//某一行被双击
rowDblclick(row, column, event) {
// console.log("双击事件", row);
this.$emit("rowDoubleClick", row);
},
// 行选中时间
handleCurrentChangeRow(val) {
this.$emit("handleCurrentChangeRow", val);
},
// 改变某一列的行的背景色
tableCellStyle({ row, column, rowIndex, columnIndex }) {
// console.log("背景色:");
// console.log("row===:", row);
// console.log("column===:", column);
// console.log("rowIndex===:", rowIndex);
// console.log("columnIndex===:", columnIndex);
//
if (row.EliminateTime < 24 && columnIndex === 7) {
return { color: "red" };
}
},
// 测试,取消荀泽
setCurrent() {
this.$refs.table.setCurrentRow();
},
// 合计 指定某一列添加合计
getSummaries(param) {
console.log(param, "heji11111");
const { columns, data } = param;
const sums = [];
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = "合计";
return;
} else if (column.property == "Amount") {
//如果是经费(正常的加减法)
const values = data.map((item) => Number(item[column.property]));
console.log(values);
if (!values.every((value) => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
var sum = 0;
if (!isNaN(value)) {
sum = Number(Number(prev) + Number(curr)).toFixed(2);
return sum;
} else {
return prev;
}
}, 0);
sums[index] += " ";
}
}
});
return sums;
},
},
//#endregion
};
</script>
<style scoped>
/* 表格表头 */
.maintenPublictable ::v-deep .el-table th,
::v-deep .el-table thead.is-group th.el-table__cell {
/* background: linear-gradient(147deg, #70c0ff, #2f9fff); */
/* background: transparent; */
background: #295d85;
color: #fff;
padding: 0;
margin: 0;
height: 3rem !important;
}
/*****滚动条影藏 */
::v-deep .el-table--scrollable-y ::-webkit-scrollbar {
display: none !important;
}
/**lable名字 */
::v-deep .el-checkbox__label {
color: #fff;
}
.fenYeStyle {
position: absolute;
/* bottom: 2rem; 第二次改动 */
/* bottom: 0rem; */
/* left: 33%; 居左*/
}
/* 背景透明 */
::v-deep .el-table tr {
background-color: transparent;
color: #fff;
}
/* 表格背景透明 */
.rollTableRow {
background: transparent;
/* border边框 */
--el-table-border-color: transparent;
}
/* 表格背景图 */
.maintenPublictable {
background: url("@/assets/imgList/tableBG.png") no-repeat;
background-size: 100% 100%;
padding: 4%;
}
/* 鼠标悬浮时 表格背景色及字体颜色 */
::v-deep .el-table tbody tr:hover > td {
background-color: rgb(65, 111, 180) !important;
color: #ffffff;
}
/* 斑马线颜色 */
::v-deep
.el-table--striped
.el-table__body
tr.el-table__row--striped
td.el-table__cell {
background: #295d85;
}
/* 箭头 */
::v-deep .el-table__expand-icon > .el-icon {
color: #f3f3f3;
}
</style>
<style scoped>
/* 页码 */
::v-deep .el-pagination__total,
::v-deep .el-pagination__jump {
color: #f3f3f3;
}
::v-deep .el-select .el-input__wrapper {
cursor: pointer;
background-color: #418de7;
border: none;
box-shadow: none;
}
::v-deep .el-select .el-input__inner {
cursor: pointer;
color: #f3f3f3;
}
::v-deep .el-pager li.is-active {
color: #f3f3f3;
cursor: default;
font-weight: 700;
background-color: #418de7;
}
/* 箭头按钮 */
::v-deep .el-input__wrapper,
::v-deep .el-pagination button:disabled,
::v-deep .el-pagination button,
::v-deep .btn-next {
background-color: #418de7;
box-shadow: none;
color: #f3f3f3;
}
::v-deep .el-pagination .el-input__inner {
color: #f3f3f3;
}
::v-deep .el-pager li.is-active,
::v-deep .el-pager li {
background-color: #418de7;
color: #f3f3f3;
}
</style>
代码中的公共js :全选反选
<script>
/**
* 全选 四个参数
* @isAll:是否被勾选(指表头), [ 类型:布尔]
* @tableData:该表格的数据 [ 类型:数组对象]
* @checkList:被选择勾选的id数组, [类型:Array]
* @isCheck:是否列表的被全部勾选(指表格数据) [类型:布尔]
*
* [返回一个对象],
* @isAll:布尔值,(指表头是否勾选),
* @checkList: checkList(指被勾选的数据)
* */
allCheck(isAll, tableData, checkList, isCheck) {
if (isAll) {
for (let i = 0; i < tableData.length; i++) {
tableData[i].check = true;
if (tableData[i].ID === undefined) {
checkList.push(tableData[i].id);
} else {
checkList.push(tableData[i].ID);
}
}
isCheck = false; //部分选中
isAll = true; //全选
} else {
for (let i = 0; i < tableData.length; i++) {
tableData[i].check = false;
checkList = [];
}
isCheck = false; //
isAll = false; //
}
return { isAll: isAll, checkList: checkList };
},
</script>