|
|
@@ -0,0 +1,209 @@
|
|
|
+<template>
|
|
|
+ <div class="containerTable">
|
|
|
+ <div class="table_box">
|
|
|
+ <div class="table-title-btn">
|
|
|
+ <slot name="table-title-btn"></slot>
|
|
|
+ </div>
|
|
|
+ <el-table ref="TableTreeRef" class="custom-table" v-loading="props.loading"
|
|
|
+ :header-cell-style="{ 'background-color': '#EEF1F6', 'border-bottom': '1px solid #EEF1F6', 'font-size': '15px', 'color': '#333', 'padding': '10px 0' }"
|
|
|
+ :data="props.tableData" :height="tableHeight" row-key="id"
|
|
|
+ style="width: 100%;">
|
|
|
+ <!-- 空内容自定义 -->
|
|
|
+ <template #empty>
|
|
|
+ <div class="flex f-c a-c ">
|
|
|
+ <img src="../../assets/images/empty.png" alt="">
|
|
|
+ <span style="font-size: 14px;color: #909399;">暂无数据</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-table-column type="selection" v-if="showSelect" :selectable="selectable" width="55" />
|
|
|
+ <el-table-column v-if="showIndex" type="index" label="序号" width="55" />
|
|
|
+ <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"
|
|
|
+ :sortable="column.sortable ? 'custom' : false" :width="column.width" :align="column.align?column.align:'center'" >
|
|
|
+ <template #default="scope">
|
|
|
+ <RouterLink v-if="column.component === 'RouterLink'" :to="getRouterLinkTo(scope.row, column)" class="custom-link">
|
|
|
+ {{ scope.row[column.prop] }}
|
|
|
+ </RouterLink>
|
|
|
+ <el-tag v-else-if="column.component === 'Tag'" :type="getTagTypeAndText(scope.row, column).type">
|
|
|
+ {{ getTagTypeAndText(scope.row, column).text }}
|
|
|
+ </el-tag>
|
|
|
+ <ImagePreview v-else-if="column.component === 'Image'" :src="getImgTo(scope.row, column)" width="50px" height="50px"></ImagePreview>
|
|
|
+ <span v-else>
|
|
|
+ {{ getDisplayText(scope.row, column) }}
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <template #header>
|
|
|
+ <slot name="search" :slotData="column"></slot>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" fixed="right" :width="props.columnwidth" align="center">
|
|
|
+ <template #default="scope">
|
|
|
+ <div class="flex j-c a-c">
|
|
|
+ <slot name="operation" class="operationClass" :operationData="scope.row"></slot>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { defineProps, ref, onMounted, defineEmits } from "vue";
|
|
|
+import type { TableInstance } from "element-plus";
|
|
|
+
|
|
|
+interface TableRow {
|
|
|
+ [key: string]: any;
|
|
|
+}
|
|
|
+interface Row {
|
|
|
+ [key: string]: any; // 假设Row是一个具有任意属性的对象
|
|
|
+}
|
|
|
+interface RouterLink {
|
|
|
+ name: string;
|
|
|
+}
|
|
|
+const emit = defineEmits([]);
|
|
|
+const props = defineProps<{
|
|
|
+ tableData: Array<TableRow>;
|
|
|
+ columnwidth: number,
|
|
|
+ loading?:boolean,
|
|
|
+ columns: {
|
|
|
+ prop: string;
|
|
|
+ label: string;
|
|
|
+ sortable?: boolean;
|
|
|
+ width?: string;
|
|
|
+ style?: string;
|
|
|
+ align?:string,
|
|
|
+ component?:string,
|
|
|
+ formatter?: (row: any, column: any, cellValue: any, index: number) => any;
|
|
|
+
|
|
|
+ }[];
|
|
|
+ showSelect: boolean;
|
|
|
+ showIndex: boolean;
|
|
|
+ tableheight?: (number | string),
|
|
|
+}>();
|
|
|
+const tableHeight = ref(props.tableheight); // 初始化表格高度
|
|
|
+
|
|
|
+const TableTreeRef = ref<TableInstance>();
|
|
|
+const TableData = ref<TableRow[]>();
|
|
|
+onMounted(() => {
|
|
|
+ let counter = 1;
|
|
|
+ TableData.value = props.tableData.map((row) => ({
|
|
|
+ ...row,
|
|
|
+ _edit: false, // 设置默认非编辑状态
|
|
|
+ counter: counter++
|
|
|
+
|
|
|
+ }));
|
|
|
+ setTimeout(() => {
|
|
|
+ const tableElement = TableTreeRef.value?.$el as HTMLElement;
|
|
|
+ if (tableElement) {
|
|
|
+ const offsetTop = tableElement.offsetTop; // 获取 offsetTop
|
|
|
+ let height = window.innerHeight;
|
|
|
+ console.log(height)
|
|
|
+ tableHeight.value = height - offsetTop - 300 + "px";
|
|
|
+ }
|
|
|
+ }, 10);
|
|
|
+
|
|
|
+
|
|
|
+});
|
|
|
+//空值处理
|
|
|
+const displayValue = (value: any) => {
|
|
|
+ return value === null || value === undefined || value === '' ? '-' : value;
|
|
|
+}
|
|
|
+const selectable = () => true;
|
|
|
+// 格式化内容配置
|
|
|
+function getRouterLinkTo(row: Row, column: any): RouterLink {
|
|
|
+ return column.formatter ? column.formatter(row, column, row[column.prop]) : { name: 'OrganizationAdd' };
|
|
|
+}
|
|
|
+function getImgTo(row: Row, column: any) {
|
|
|
+ return row[column.prop];
|
|
|
+}
|
|
|
+function getTagTypeAndText(row: Row, column: any) {
|
|
|
+ // 使用 formatter 返回一个对象,包含 type 和 text
|
|
|
+ return column.formatter ? column.formatter(row, column, row[column.prop]) : { type: 'primary', text: row[column.prop] };
|
|
|
+}
|
|
|
+function getDisplayText(row: Row, column: any): string {
|
|
|
+ return column.formatter ? column.formatter(row, column, row[column.prop]) :displayValue(row[column.prop]);
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+.el-table .el-table__cell .routerlick > a {
|
|
|
+ color: red;
|
|
|
+}
|
|
|
+
|
|
|
+.containerTable {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ width: 100%;
|
|
|
+ height: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.table_box {
|
|
|
+ flex: 1;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ .table_item_container {
|
|
|
+ padding: 0;
|
|
|
+ margin-left: 20px;
|
|
|
+
|
|
|
+ .table_item {
|
|
|
+ margin: 5px 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-title-btn {
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ :deep(.el-button) {
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 自定义树状表格图标 */
|
|
|
+
|
|
|
+// /* 有子节点 且未展开 */
|
|
|
+// .custom-table :deep(.el-table__expand-icon) {
|
|
|
+// display: flex;
|
|
|
+// align-items: center;
|
|
|
+// justify-content: center;
|
|
|
+// width: 18px;
|
|
|
+// height: 18px;
|
|
|
+// background: url("../../assets/icons/caretRight.svg") no-repeat;
|
|
|
+// background-size: auto;
|
|
|
+
|
|
|
+// svg {
|
|
|
+// display: none;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+// /* 有子节点 且已展开 */
|
|
|
+// .custom-table :deep(.el-table__expand-icon--expanded) {
|
|
|
+// display: inline-block;
|
|
|
+// display: flex;
|
|
|
+// align-items: center;
|
|
|
+// justify-content: center;
|
|
|
+// width: 18px;
|
|
|
+// height: 18px;
|
|
|
+// content: "";
|
|
|
+// background: url("../../assets/icons/caretRight.svg") no-repeat;
|
|
|
+// background-size: auto;
|
|
|
+// transform: rotate(90deg);
|
|
|
+
|
|
|
+// svg {
|
|
|
+// display: none;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+:deep(.el-table) {
|
|
|
+ .el-table__row--level-1 {
|
|
|
+ background-color: #eef1f6;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.operationClass {
|
|
|
+ .el-button {
|
|
|
+ margin: 0 7px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|