275 lines
6.4 KiB
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>
|