pms-front/src/components/CustomTable.vue

275 lines
6.4 KiB
Vue

<template>
<div class="custom-table" ref="tableContainer">
{{ computedTableHeight }}
<el-table
ref="elTableRef"
:data="tableData"
v-bind="$attrs"
@selection-change="handleSelectionChange"
:border="border"
:highlight-current-row="highligt"
@row-click="rowClick"
@sort-change="sortChange"
:row-key="rowKey"
:height="tableHeight"
@select="selected"
@select-all="selectAll"
>
<el-table-column
reserve-selection
v-if="showSelection"
type="selection"
width="55"
:selectable="selectable"
/>
<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"
:sortable="column.sortable"
>
<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",
},
tableHeight: {
type: String,
default: "100%",
},
selectable:{
type: Function,
default: ()=>true,
}
},
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);
},
setCurrentRow(row) {
this.$refs.elTableRef?.setCurrentRow(row);
},
clearSelection() {
this.$refs.elTableRef?.clearSelection();
},
toggleRowSelection(row, selected) {
this.$refs.elTableRef?.toggleRowSelection(row, selected);
},
sortChange(data) {
this.$emit("sortChange", data);
},
selected(arr, row) {
this.$emit("selected", { arr, row });
},
selectAll(arr) {
this.$emit("selectAll", arr);
},
},
updated() {
if (this.$refs.elTableRef && this.$refs.elTableRef.doLayout) {
this.$refs.elTableRef.doLayout();
}
},
mounted() {},
beforeDestroy() {},
};
</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%;
flex: none;
font-weight: 600;
font-size: 14px;
}
::v-deep .el-table th {
text-align: center;
}
::v-deep .operation-column .el-button-text {
font-weight: 600 !important;
font-size: 14px !important;
}
::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;
}
::v-deep .el-table__fixed {
background-color: #fff;
}
::v-deep .el-table {
max-height: 99%;
}
::v-deep .el-table .el-table__body .el-table__cell {
padding: 15px 0 !important;
}
</style>