<template> <!-- 显示表格 --> <div class="h-100 page-table" ref="tableBox" v-loading="listInfo.loading" element-loading-text="加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(255,255,255,0.3)" > <el-table class="h-100" :data="data" row-key="id" default-expand-all :class="className" :max-height="listInfo.tableHeight" :header-cell-style="{ textAlign: 'center' }" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @select-all="handleSelectionChange" @selection-change="handleSelectionChange" > <el-table-column v-if="checkBox" type="selection" width="55" align="center" :selectable="checkboxInit" /> <el-table-column v-if="tabIndex" label="序号" align="center" :width="fieldList.length === 0 ? '' : 60" > <template slot-scope="scope"> <span>{{ scope.$index + 1 + (listInfo.query.current - 1) * listInfo.query.size }}</span> </template> </el-table-column> <el-table-column v-for="(item, index) in fieldList" :key="index" :prop="item.value" :label="item.label" :fixed="item.fixed" :align="item.align ? item.align : 'center'" :width="item.width" :min-width="`${item.minWidth}`" :show-overflow-tooltip="item.tooltip" > <template slot-scope="scope"> <!-- solt自定义列--> <template v-if="item.type === 'slot'"> <slot :name="'col-' + item.value" :row="scope.row" /> </template> <!-- 嵌套表格 --> <template v-else-if="item.children"> <el-table-column v-for="(childItem, childIndex) in item.children" :key="childIndex" :prop="childItem.value" :label="childItem.label" align="center" :width="item.width" :min-width="item.minWidth" /> </template> <!-- 图片 --> <el-image v-else-if="item.type === 'image' && scope.row[item.value]" :src="scope.row[item.value]" fit="fill" ></el-image> <!-- 其他 --> <span v-else> {{ getDataName({ dataList: listTypeInfo[item.list], value: "value", label: "key", data: scope.row[item.value] }) || "-" }} </span> </template> </el-table-column> <el-table-column v-if="handle" :key="'handle'" :fixed="handle.fixed" align="center" :label="handle.label" :width="handle.width" > <template v-slot="scope"> <template v-for="(item, index) in handle.btList"> <!-- 自定义操作类型 --> <slot v-if="item.slot" :name="`bt-${item.event}`" :data="{ item, row: scope.row }" /> <!-- 操作按钮 --> <el-button v-if=" !item.slot && item.show && (!item.ifRender || item.ifRender(scope.row)) " :key="index" :size="item.size || 'small'" :type="item.type" :icon="item.icon" v-has="item.has ? item.has : ''" :disabled="item.disabled" :loading="scope.row[item.loading]" @click="handleClick(item.event, scope.row, scope.$index)" > {{ item.label }} </el-button> </template> </template> </el-table-column> </el-table> <!-- 分页组件 --> <template v-if="pagination"> <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="listInfo.total" :pager-count="5" :page-sizes="[10, 20, 30, 40]" :page-size="listInfo.query.size" :current-page.sync="listInfo.query.current" @current-change="handleCurrentChange" @size-change="handleSizeChange" /> </template> </div> </template> <script> export default { props: { //自定义样式名 className: { type: String }, //获取数据的接口 apiUrl: { type: String }, //是否显示序号 tabIndex: { type: Boolean, default: false }, //表格字段配置 fieldList: { type: Array, default: () => { return []; } }, //刷新 refresh: { type: Number }, //重置当前页 initCurpage: { type: Number }, //表格数据 data: { type: Array }, //是否有选中框 checkBox: { type: Boolean, default: false }, //操作栏配置 handle: { type: Object }, //监听高度 listenHeight: { type: Boolean, default: true }, //类型列表 listTypeInfo: { type: Object, default: () => { return {}; } }, //是否分页 pagination: { type: Boolean, default: false }, //查询条件 query: { type: Object, default: () => { return {}; } }, //表格最大高度 tableHeight: { type: Number }, //表格数据展示类型 tableType: { type: String }, loading: { type: Boolean, default: true }, //用于区分多个表格选中的结果 type: { type: String, default: "all" } }, data() { return { //列表相关 listInfo: { tableHeight: null, //表格最大高度 total: 0, //总条数 loading: false, //加载动画 query: { //查询条件 current: 1, //当前页 size: 10 //每页条数 } } }; }, watch: { initCurpage() { this.listInfo.query.current = 1; }, refresh: { handler(newVal, oldVal) { if (this.apiUrl === "") return; this.getList(this.apiUrl); }, deep: true } }, mounted() { setTimeout(() => { this.listInfo.tableHeight = this.getTableHeight(); }, 0); window.addEventListener("resize", () => { this.listInfo.tableHeight = this.getTableHeight(); }); }, methods: { // 处理参数 handleParams() { const obj = {}; for (const key in this.query) { // if (this.query[key] || this.query[key] === 0) { obj[key] = this.query[key]; // } } // 如果不需要分页,则无分页相关参数 const dataObj = this.pagination ? { data: obj } : { data: {} }; return this.pagination ? { ...this.listInfo.query, ...dataObj } : dataObj; }, //选中数据 handleSelectionChange(rows) { this.$emit("handleEvent", this.type, rows); }, //派发按钮点击事件 handleClick(event, data, index) { this.$emit("handleClick", event, data, index); }, /** * 通过key找到在列表中对应的显示 * @param {Object} obj * @param obj.dataList 数据列表 * @param obj.value 数据的值对应的字段名称 例如 'value' * @param obj.label 数据的说明对应的字段名称 例如 'label' * @param obj.data 当前传入的数据值 * @return name 返回当前传入值在数组中对应的名字 */ getDataName(obj) { let name = obj.data; if (Array.isArray(obj.dataList) && obj.dataList.length > 0) { for (let i = 0; i < obj.dataList.length; i++) { if (obj.dataList[i][obj.value] === obj.data) { name = obj.dataList[i][obj.label]; } } } return name; }, handleCurrentChange(val) { this.listInfo.query.current = val; //当前页 this.$emit("currentPage", val); this.getList(this.apiUrl); }, handleSizeChange(val) { this.listInfo.query.size = val; //当前一页多少条 this.getList(this.apiUrl); }, //获取数据 getList(url) { // return new Promise((resolve, reject)=>{ //每次调用接口自动绑定最新数据 this.listInfo.loading = true; this.$http .post(url, this.handleParams()) .then(res => { this.listInfo.loading = false; if (res.data.code === 200 || res.data.code === 1) { //使外面可以访问到表格数据 let arr = Array.isArray(res.data.data) ? res.data.data : res.data.data.list; if (this.tableType === "tree") { arr = this.$fn.handleTree(arr); } if (arr) { arr.forEach(item => { item.createTime = this.$fn.switchTime( item.createTime, "YYYY-MM-DD hh:mm:ss" ); item.updateTime = this.$fn.switchTime( item.updateTime, "YYYY-MM-DD hh:mm:ss" ); }); this.$emit("update:data", arr); } else { this.$emit("update:data", []); } if (this.pagination) { this.listInfo.total = res.data.data.total; } // resolve(res) } else { this.$message({ showClose: true, message: res.data.msg, type: "error", duration: 3000 }); // reject() } }) .catch(err => { console.log(err); this.listInfo.loading = false; // reject() }); // }) }, //得到表格高度 getTableHeight() { //当表格存在的时候才执行操作 if (document.getElementsByClassName("el-table").length === 0) { return; } let _baseHeight = this.pagination ? 42 : 0; if (this.$refs.tableBox && this.$refs.tableBox.offsetHeight) { let resultHeight = this.$refs.tableBox.offsetHeight; let _height = resultHeight - _baseHeight; return _height; } }, //判断是否可以被选中 checkboxInit(row, index) { if (row.registered) { return 0; //不可勾选 } else { return 1; //可勾选 } } } }; </script> <style lang="scss" scoped> /deep/ .el-table { @include fd(); // .el-table__body tr.hover-row > td { // background-color: transparent; // } .el-table__body tr.hover-row > td { background-color: var(--selecthover) !important; } .el-table__fixed-right::before, .el-table__fixed::before { background-color: transparent; } .el-table__fixed-right-patch { background-color: aqua; } .el-table__fixed-right-patch { border-bottom-color: aqua; } .el-table__body-wrapper { flex: 1; } } /deep/ .el-pagination { margin-top: 10px; } /deep/ .el-pagination.is-background { .el-pager li:not(.disabled).active { color: #fff; background-color: #409eff !important; } } </style>