247 lines
6.1 KiB
Vue
247 lines
6.1 KiB
Vue
|
|
<template>
|
||
|
|
<div class="custom-table" ref="tableContainer">
|
||
|
|
<el-table
|
||
|
|
ref="elTableRef"
|
||
|
|
:data="tableData"
|
||
|
|
:max-height="computedTableHeight"
|
||
|
|
v-bind="$attrs"
|
||
|
|
@selection-change="handleSelectionChange"
|
||
|
|
:border="border"
|
||
|
|
:highlight-current-row="highligt"
|
||
|
|
@row-click="rowClick"
|
||
|
|
:row-key="rowKey"
|
||
|
|
:maxHeight="maxHeight"
|
||
|
|
>
|
||
|
|
<el-table-column v-if="showSelection" type="selection" width="55" />
|
||
|
|
<el-table-column v-if="showIndex" type="index" width="50" label="序号" />
|
||
|
|
<template>
|
||
|
|
<el-table-column
|
||
|
|
v-bind="column"
|
||
|
|
:prop="column.prop"
|
||
|
|
:label="column.label"
|
||
|
|
v-for="(column, index) in columns"
|
||
|
|
:key="index"
|
||
|
|
>
|
||
|
|
<template #default="scope">
|
||
|
|
<slot :name="column.prop" :row="scope.row">
|
||
|
|
<template v-if="column.type === 'multiButton'">
|
||
|
|
<div class="button-group">
|
||
|
|
<el-button
|
||
|
|
v-for="(data,index) in scope.row[column.prop]"
|
||
|
|
:key="index"
|
||
|
|
type="text"
|
||
|
|
size="small"
|
||
|
|
@click="column.Event(data, scope.row)"
|
||
|
|
>
|
||
|
|
{{ column.callback(data, scope.row) }}
|
||
|
|
</el-button>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<template v-else-if="column.type === 'status'">
|
||
|
|
<span
|
||
|
|
v-if="column.callback"
|
||
|
|
v-html="column.callback(scope.row[column.prop], scope.row)"
|
||
|
|
></span>
|
||
|
|
<span v-else>
|
||
|
|
{{ scope.row[column.prop] }}
|
||
|
|
</span>
|
||
|
|
</template>
|
||
|
|
<template v-else-if="column.type === 'button'">
|
||
|
|
<div
|
||
|
|
v-html="column.callback(scope.row[column.prop], scope.row)"
|
||
|
|
@click="column.Event(scope.row[column.prop], scope.row)"
|
||
|
|
></div>
|
||
|
|
</template>
|
||
|
|
<template v-else-if="column.type === 'array'">
|
||
|
|
<div>
|
||
|
|
{{ column.callback(scope.row[column.prop], scope.row) }}
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<template v-else>
|
||
|
|
{{ scope.row[column.prop] }}
|
||
|
|
</template>
|
||
|
|
</slot>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</template>
|
||
|
|
</el-table>
|
||
|
|
<div
|
||
|
|
class="pagination-container"
|
||
|
|
ref="paginationContainer"
|
||
|
|
v-if="showPagination"
|
||
|
|
>
|
||
|
|
<el-pagination
|
||
|
|
:current-page="currentPage"
|
||
|
|
:page-size="pageSize"
|
||
|
|
:total="total"
|
||
|
|
:page-sizes="pageSizes"
|
||
|
|
layout="total, sizes, prev, pager, next, jumper"
|
||
|
|
@size-change="handleSizeChange"
|
||
|
|
@current-change="handleCurrentChange"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
export default {
|
||
|
|
props: {
|
||
|
|
columns: {
|
||
|
|
type: Array,
|
||
|
|
required: true,
|
||
|
|
},
|
||
|
|
tableData: {
|
||
|
|
type: Array,
|
||
|
|
default: () => [],
|
||
|
|
},
|
||
|
|
showSelection: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
showIndex: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
showPagination: {
|
||
|
|
type: Boolean,
|
||
|
|
default: true,
|
||
|
|
},
|
||
|
|
total: {
|
||
|
|
type: Number,
|
||
|
|
default: 0,
|
||
|
|
},
|
||
|
|
pageSizes: {
|
||
|
|
type: Array,
|
||
|
|
default: () => [10, 20, 30, 50],
|
||
|
|
},
|
||
|
|
maxHeight: {
|
||
|
|
type: String,
|
||
|
|
default: "100%",
|
||
|
|
},
|
||
|
|
offsetHeight: {
|
||
|
|
type: Number,
|
||
|
|
default: 0,
|
||
|
|
},
|
||
|
|
border: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
multiSelect: {
|
||
|
|
type: Boolean,
|
||
|
|
default: true,
|
||
|
|
},
|
||
|
|
highligt: {
|
||
|
|
type: Boolean,
|
||
|
|
default: true,
|
||
|
|
},
|
||
|
|
rowClick: {
|
||
|
|
type: Function,
|
||
|
|
default: () => "",
|
||
|
|
},
|
||
|
|
rowKey: {
|
||
|
|
type: String,
|
||
|
|
default: "id",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
data() {
|
||
|
|
return {
|
||
|
|
currentPage: 1,
|
||
|
|
pageSize: 10,
|
||
|
|
tableContainer: null,
|
||
|
|
paginationContainer: null,
|
||
|
|
computedTableHeight: null,
|
||
|
|
elTableRef: null,
|
||
|
|
};
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
handleSelectionChange(selection) {
|
||
|
|
this.$emit("selection-change", selection);
|
||
|
|
},
|
||
|
|
handleSizeChange(val) {
|
||
|
|
this.pageSize = val;
|
||
|
|
this.$emit("size-change", val);
|
||
|
|
},
|
||
|
|
handleCurrentChange(val) {
|
||
|
|
this.currentPage = val;
|
||
|
|
this.$emit("current-change", val);
|
||
|
|
},
|
||
|
|
updateTableHeight() {
|
||
|
|
this.$nextTick(() => {
|
||
|
|
if (this.tableContainer) {
|
||
|
|
const parentElement = this.tableContainer.parentElement;
|
||
|
|
const parentHeight = parentElement.clientHeight;
|
||
|
|
const tableTop =
|
||
|
|
this.tableContainer.getBoundingClientRect().top -
|
||
|
|
parentElement.getBoundingClientRect().top;
|
||
|
|
const paginationHeight = this.showPagination
|
||
|
|
? this.paginationContainer.offsetHeight + 30
|
||
|
|
: 0; // 加上 margin-top
|
||
|
|
this.computedTableHeight = parentHeight - tableTop - paginationHeight;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
},
|
||
|
|
setCurrentRow(row) {
|
||
|
|
this.$refs.elTableRef.setCurrentRow(row);
|
||
|
|
},
|
||
|
|
clearSelection() {
|
||
|
|
this.$refs.elTableRef?.clearSelection();
|
||
|
|
},
|
||
|
|
toggleRowSelection(row, selected) {
|
||
|
|
this.$refs.elTableRef?.toggleRowSelection(row, selected);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
mounted() {
|
||
|
|
this.updateTableHeight();
|
||
|
|
window.addEventListener("resize", this.updateTableHeight);
|
||
|
|
},
|
||
|
|
beforeDestroy() {
|
||
|
|
window.removeEventListener("resize", this.updateTableHeight);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style lang="scss" scoped>
|
||
|
|
.custom-table {
|
||
|
|
width: 100%;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
.pagination-container {
|
||
|
|
margin-top: 10px;
|
||
|
|
display: flex;
|
||
|
|
justify-content: flex-end;
|
||
|
|
}
|
||
|
|
::v-deep .el-scrollbar__wrap--hidden-default {
|
||
|
|
min-height: 100px;
|
||
|
|
}
|
||
|
|
::v-deep .el-table {
|
||
|
|
--el-table-text-align: center;
|
||
|
|
width: 100%;
|
||
|
|
}
|
||
|
|
|
||
|
|
::v-deep .el-table th {
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
::v-deep .el-table .cell {
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 如果操作列需要特殊处理,可以添加以下样式 */
|
||
|
|
::v-deep .operation-column .cell {
|
||
|
|
text-align: center;
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
::v-deep .el-table__inner-wrapper::before {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
::v-deep .el-table-column--selection {
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
.button-group ::v-deep .el-button {
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
</style>
|