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: {// 表头数据 文案和绑定值,以及需要特殊处理的slottype: 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, //序号添加自定义htmlreserveSelection: 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,890getMoneyK(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>