el-table 组件二次封装(vue2)
PublicTable.vue
<!-- 公共表格组件 -->
<template>
<div class="table-common">
<el-table v-loading="loading" :ref="tableid" border style="width: 100%" :data="tableDatas" :row-key="rowKey"
@selection-change="handleSelectionChange" @select="selectDataChange" @select-all="selectAllDataChange"
:height="tableHeight" :header-cell-style="headerCellStyle" :row-style="rowStyle" highlight-selection-row
:max-height="maxHeight" @row-click="handleRowClick" :tooltip-effect="configFlag.tooltip || 'dark'">
<!-- 当数据为空时,如果想添加一个表达是空数据的图片,可以在这里设置,如果没有就不用管了 -->
<template slot="empty">
<el-empty class="empty_box" :image-size="55">
<template slot="image">
<img src="@/assets/icons/images/nodata.png">
</template>
</el-empty>
</template>
<!-- 全选单选 -->
<el-table-column v-if="configFlag.selection" align="center" width="55" type="selection"
:reserve-selection="configFlag.reserveSelection" />
<!-- 序号列 -->
<el-table-column type="index" v-if="configFlag.index" :label="configFlag.indexName || '序号'"
:width="configFlag.indexWidth || 50" align="center" :fixed="configFlag.indexFixed || 'left'">
<template slot-scope="scope">
<!-- 每页都是从 1 开始 -->
{{ scope.$index + 1 }}
<!-- 第二页从 11 开始 -->
<!-- {{ (pageValue.pageNum - 1) * 10 + (scope.$index + 1) }} -->
</template>
</el-table-column>
<!-- 循环遍历表头展示数据 -->
<el-table-column v-for="item in columnsCopy" :key="item.fieldIndex" :width="item.width || ''"
:min-width="item.minWidth || ''" :prop="item.fieldIndex" :label="item.label" :align="item.align || 'center'"
:sortable="item.sortable" :fixed="item.fixed || false" header-align="center"
:show-overflow-tooltip="item.showOverFlowTooltip" :filters="item.filters ? item.filters : null"
:filter-method="item.filters ? item.filtersMethod : null" :selectable="(row) => !row.isSelected">
<template slot="header" slot-scope="{ column }">
{{ column.label }}
<el-tooltip class="item" effect="dark" v-if="item.headertip" :content="item.headertip" placement="top-start">
<i class="el-icon-warning"></i>
</el-tooltip>
</template>
<template slot-scope="scope">
<!-- {{ scope }} -->
<!-- 枚举值 -->
<div v-if="item.type == 'statMap'">
{{ statMaps(item.options)[scope.row[item.fieldIndex]] || "--" }}
</div>
<!-- 需提示过长信息 -->
<div v-else-if="item.showOverFlowTooltip">
<div class="show-tooltip">
{{ scope.row[item.fieldIndex] || "--" }}
</div>
</div>
<!-- 保留两位小数 -->
<div v-else-if="item.type == 'tofix2'">
{{
scope.row[item.fieldIndex]
? Number(scope.row[item.fieldIndex]).toFixed(2)
: "--"
}}
</div>
<!-- 金额千分位展示,项目需求,所以暂时就加上了,主要是做个示例,大家可以参考怎么自定义列的一些方法 -->
<div v-else-if="item.type == 'money'">
<span>{{ getMoneyK(scope.row[item.fieldIndex]) || "--" }}</span>
</div>
<!-- 根据需求添加效果 返回的slot可以优化.自己来吧.可以实现操作列等 -->
<slot v-else-if="item.type == undefined && item.slotname" :scope="scope" :field="item.fieldIndex"
:name="item.slotname"></slot>
<!-- 最普通的情况 -->
<div v-else>
<span>{{ scope.row[item.fieldIndex] || "--" }}</span>
</div>
</template>
</el-table-column>
</el-table>
<el-pagination small v-if="configFlag.needPage" background :total="pageValue.total" :page-count="pageValue.pageNum"
:page-size="pageValue.pageSize" :page-sizes="pageSizes" :current-page.sync="pageValue.pageNum"
:layout="pageValue.pageLayout || pageLayout" class="_pagination" @size-change="sizeChange"
@current-change="currentChange" @prev-click="prevClick" @next-click="nextClick" />
</div>
</template>
<script>
export default {
name: "Table",
data() {
return {
tableDatas: [],
loading: true,
pageLayout: "total,prev, pager, next, jumper",
columnsCopy: []
};
},
props: {
// 多选保存选中数据
rowKey: {
default: () => (row) => row.index,
},
// 为表头设计样式
headerCellStyle: {
default: () => {
return { background: "rgb(243,248,254)" };
},
},
// 为每一行设计样式,比如设置每行的高度等等
rowStyle: {
default: () => {
return { height: "50px" };
},
},
columns: {
// 表头数据 文案和绑定值,以及需要特殊处理的slot
type: Array,
default: () => [],
},
tableData: {
type: Array, // 后台数据
default: () => [],
},
tableid: {
type: String,
default: "publicTable",
},
// 分页参数
pageValue: {
// 分页数据
type: Object,
default: () => {
return {
pageNum: 1,
pageSize: 10,
total: 0,
currentPage: 1, //当前页
};
},
},
// 每页多少条的选项
pageSizes: {
type: Array,
default: () => {
return [10, 20, 50, 100];
},
},
// 表格配置项
configFlag: {
// 配置 其他table配置依次添加
type: Object,
default: () => {
return {
needPage: false, // 是否需要分页
selection: false, // 是否需要多选
index: false, // 是否需要序号
indexWidth: 70, //序号列宽
btn: false, //序号添加自定义html
reserveSelection: false,
tooltip: 'dark'
// 这里不全面,可根据实际情况添加
};
},
},
tableHeight: {
// 可以监听屏幕高度获取。
// 高度
// type: Number || String ,
default: () => null,
},
maxHeight: {
// 可以监听屏幕高度获取。
// 最大高度
type: Number || String,
default: () => 900,
},
// 是否可以点击行选中多选框
rowClickSelect: {
type: Boolean,
default: true
}
},
watch: {
tableData: {
handler: function (newvalue) {
this.tableDatas = newvalue;
this.loading = false;
},
deep: true,
},
columns: {
handler: function (newvalue) {
this.columnsCopy = newvalue;
},
deep: true,
}
},
beforeUpdate() {
this.tableDatas = this.$props.tableData;
this.loading = false;
},
computed: {},
mounted() {
this.columnsCopy = this.$props.columns;
},
methods: {
// 用于表格中字段是枚举值的列 比如性别 0 代表女 1代表男,就不需要对后台数据单独处理了
handleRowClick(row) {
if (this.rowClickSelect) {
row.isSelected = !row.isSelected;
this.$refs[this.tableid].toggleRowSelection(row);
}
},
statMaps(list) {
if (!list) return;
let obj = {};
list.forEach((item) => {
obj[item.value || item.id] = item.label || item.value;
});
return obj;
},
// 金额千位展示:1,234,567,890
getMoneyK(money) {
if (typeof money === "number") {
money = money.toString();
}
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(money)) {
money = money.replace(pattern, "$1,$2");
}
return money;
},
// 清空选中
clearSelected() {
// 父组件通过ref调用clearSelected方法,例如 this.$refs.clearTable.clearSelected()
this.$refs[this.tableid]?.clearSelection();
},
/*
默认选中
需要默认选中的在组件中通过this.$refs[tableid].selected(默认选中的数据:Array)
*/
selected(data) {
if (data.length > 0) {
data.forEach((item) => {
this.$refs[this.tableid].toggleRowSelection(item, true);
});
}
},
// 设置条数
sizeChange(size) {
this.$emit("sizeChange", size);
},
// 翻页,直接跳转
currentChange(page) {
this.$emit("handleChange", page);
},
//上一页
prevClick(val) {
this.$emit("prevClick", val);
},
//下一页
nextClick(val) {
this.$emit("nextClick", val);
},
// 多选
handleSelectionChange(val) {
this.$emit("handleSelectionChange", val);
},
//点击选中取消选中
selectDataChange(val, row) {
this.$emit("selectDataChange", val, row);
},
selectAllDataChange(val) {
this.$emit("selectAllDataChange", val);
},
// 多选
handleSelection(val, row) {
this.$emit("handleSelection", { val, row });
},
handleCellEnter(row, column, cell, event) {
this.$emit("handleCellEnter", { row, column, cell, event });
},
//编辑
handleEdit(index, row, colIndex, field) {
this.$emit("handleEdit", { index, row, colIndex, field });
},
//下拉框事件
onSelected(index, row, field) {
this.$emit("onSelected", { index, row, field });
},
//按钮点击事件
onClickBtn(index, row) {
this.$emit("onClickBtn", { index, row });
},
filterHandler(value, row, column) {
const property = column["property"];
return row[property] === value;
},
/**重构表格布局 */
handleResize() {
this.$nextTick(() => {
this.$refs[this.tableid].doLayout();
});
},
},
};
</script>
<style lang="scss" scoped>
.show-tooltip {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
}
/* 修改Tooltip样式 */
::v-deep .el-tooltip__popper.is-dark {
background-color: #fff;
/* 设置白色背景 */
color: #000;
/* 设置黑色字体 */
}
._pagination {
width: 100%;
margin: 5px 0;
text-align: center;
}
.table-common {
height: calc(100% - 30px);
}
::v-deep .empty_box {
.el-empty__description {
margin-top: 0;
p {
line-height: 50px;
}
}
}
</style>
用法:
<template>
<div>
<public-table ref="taskTable" :rowKey="(row) => row.id" :tableData="tableData" :columns="columns" :configFlag="tableConfig" @handleSelectionChange="selectChange" @sizeChange="handleSizeChange" @handleChange="handlePageChange" table-height="100%"></public-table>
</div>
</template>
<script>
export default {
data(){
columns:[
{ label: '任务名称', fieldIndex: 'taskName', showOverFlowTooltip: true },
],
tableConfig:{
needPage: false, // 是否需要分页
index: true, // 是否需要序号
selection: true, // 是否需要多选
reserveSelection: false, // 是否需要支持跨页选择
indexFixed: 'left', // 序号列固定
},
tableData:[], // 表格数据
pageValue: {
// 分页参数
total: 0,
pageNum: 1,
pageSize: 10,
pageLayout: "total,sizes,prev,pager,next,jumper"
},
selectList:[], // 表格选中数据
},
methods:{
// 表格多选事件
selectChange(e){
this.selectList = e;
},
// 表格分页-页容改变
handleSizeChange(e) {
this.pageValue.pageSize = e;
this.pageValue.pageNum = 1;
},
// 表格分页-页数改变
handlePageChange(e) {
this.pageValue.pageNum = e;
}
}
}
</script>