2025-06-10 09:31:15 +08:00
|
|
|
<template>
|
|
|
|
<el-table
|
|
|
|
ref="tableRef"
|
|
|
|
size="small"
|
|
|
|
:data="data"
|
|
|
|
:border="border"
|
|
|
|
:stripe="stripe"
|
|
|
|
:height="height"
|
|
|
|
:max-height="maxHeight"
|
|
|
|
:highlight-current-row="highlightCurrentRow"
|
|
|
|
:row-key="getRowKey"
|
|
|
|
:row-class-name="rowClassName"
|
|
|
|
:row-style="rowStyle"
|
|
|
|
:show-header="showHeader"
|
|
|
|
:show-summary="showSummary"
|
|
|
|
:summary-method="summaryMethod"
|
|
|
|
:span-method="spanMethod"
|
|
|
|
:default-expand-all="defaultExpandAll"
|
|
|
|
:tree-props="treeProps"
|
|
|
|
:header-cell-style="headerCellStyle"
|
|
|
|
:cell-style="cellStyle"
|
2025-06-27 14:01:42 +08:00
|
|
|
:show-overflow-tooltip="showOverflowTooltip"
|
|
|
|
style="width: 100%"
|
2025-06-10 09:31:15 +08:00
|
|
|
@row-click="rowClick"
|
|
|
|
@row-dblclick="rowDblclick"
|
|
|
|
>
|
|
|
|
<el-table-column
|
|
|
|
v-if="showSelection"
|
|
|
|
type="selection"
|
2025-06-27 14:01:42 +08:00
|
|
|
:selectable="selectable"
|
2025-06-10 09:31:15 +08:00
|
|
|
reserve-selection
|
|
|
|
width="60"
|
2025-06-27 14:01:42 +08:00
|
|
|
:show-overflow-tooltip="false"
|
2025-06-10 09:31:15 +08:00
|
|
|
/>
|
2025-06-27 14:01:42 +08:00
|
|
|
<template v-if="showIndex">
|
|
|
|
<el-table-column v-if="showPagination" label="序号" width="60">
|
|
|
|
<template #default="{ $index }">
|
|
|
|
{{ serialNumber(pagination, $index) }}
|
|
|
|
</template>
|
|
|
|
</el-table-column>
|
|
|
|
<el-table-column
|
|
|
|
v-if="!showPagination"
|
|
|
|
label="序号"
|
|
|
|
width="60"
|
|
|
|
type="index"
|
|
|
|
/>
|
|
|
|
</template>
|
2025-06-10 09:31:15 +08:00
|
|
|
<slot></slot>
|
|
|
|
</el-table>
|
|
|
|
<div v-if="showPagination || slots.button" class="table_footer">
|
|
|
|
<div>
|
|
|
|
<slot name="button"></slot>
|
|
|
|
</div>
|
|
|
|
<app-pagination
|
|
|
|
v-if="showPagination"
|
|
|
|
v-model:pagination="pagination"
|
|
|
|
@get-data="emits('get-data')"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
import { useSlots, useTemplateRef } from "vue";
|
|
|
|
import AppPagination from "@/components/pagination/index.vue";
|
|
|
|
import { serialNumber } from "@/assets/js/utils.js";
|
|
|
|
|
|
|
|
const slots = useSlots();
|
|
|
|
defineOptions({
|
|
|
|
name: "AppTable",
|
|
|
|
});
|
|
|
|
const props = defineProps({
|
2025-07-21 11:32:02 +08:00
|
|
|
data: { type: Array, required: true },
|
|
|
|
showPagination: { type: Boolean, default: true },
|
|
|
|
showIndex: { type: Boolean, default: true },
|
|
|
|
showSelection: { type: Boolean, default: false },
|
|
|
|
stripe: { type: Boolean, default: true },
|
|
|
|
border: { type: Boolean, default: true },
|
|
|
|
showHeader: { type: Boolean, default: true },
|
|
|
|
highlightCurrentRow: { type: Boolean, default: false },
|
|
|
|
showSummary: { type: Boolean, default: false },
|
|
|
|
defaultExpandAll: { type: Boolean, default: false },
|
|
|
|
rowKey: { type: [String, Function] },
|
|
|
|
maxHeight: { type: [String, Number] },
|
|
|
|
height: { type: [String, Number] },
|
|
|
|
rowClassName: { type: Function },
|
|
|
|
rowStyle: { type: Function },
|
|
|
|
summaryMethod: { type: Function },
|
|
|
|
spanMethod: { type: Function },
|
|
|
|
selectable: { type: Function },
|
2025-06-10 09:31:15 +08:00
|
|
|
treeProps: {
|
|
|
|
type: Object,
|
|
|
|
default: () => ({ hasChildren: "hasChildren", children: "children" }),
|
|
|
|
},
|
2025-07-21 11:32:02 +08:00
|
|
|
headerCellStyle: { type: Object, default: () => ({}) },
|
|
|
|
cellStyle: { type: [Object, Function], default: () => ({}) },
|
|
|
|
showOverflowTooltip: { type: Boolean, default: true },
|
2025-06-10 09:31:15 +08:00
|
|
|
});
|
|
|
|
const pagination = defineModel("pagination", {
|
|
|
|
type: Object,
|
|
|
|
default: () => ({
|
|
|
|
currentPage: 1,
|
|
|
|
pageSize: 10,
|
|
|
|
total: 0,
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
const emits = defineEmits(["get-data", "row-click", "row-dblclick"]);
|
|
|
|
const tableRef = useTemplateRef("tableRef");
|
|
|
|
const getRowKey = (row) => {
|
|
|
|
if (!props.rowKey) return;
|
|
|
|
if (typeof props.rowKey === "string") return row[props.rowKey];
|
|
|
|
else return props.rowKey(row);
|
|
|
|
};
|
|
|
|
const rowClick = (row, column, event) => {
|
|
|
|
emits("row-click", row, column, event);
|
|
|
|
};
|
|
|
|
const rowDblclick = (row, column, event) => {
|
|
|
|
emits("row-dblclick", row, column, event);
|
|
|
|
};
|
|
|
|
const getSelectionRows = () => {
|
|
|
|
return tableRef.value.getSelectionRows();
|
|
|
|
};
|
|
|
|
const clearSelection = () => {
|
|
|
|
return tableRef.value.clearSelection();
|
|
|
|
};
|
|
|
|
const toggleRowSelection = (value, selected = true) => {
|
|
|
|
tableRef.value.toggleRowSelection(value, selected);
|
|
|
|
};
|
|
|
|
defineExpose({
|
|
|
|
getSelectionRows,
|
|
|
|
clearSelection,
|
|
|
|
toggleRowSelection,
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.table_footer {
|
|
|
|
margin-top: 20px;
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
}
|
|
|
|
</style>
|