BasicTable.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <div class="basic-table">
  3. <el-table
  4. ref="tableRef"
  5. v-bind="props.tableConfig"
  6. v-loading="props.tableConfig.loading"
  7. :data="props.tableData"
  8. @selection-change="handleSelectionChange"
  9. border
  10. >
  11. <template #empty>
  12. <img :src="EmptyImg" alt="empty" />
  13. <span>{{ props.tableConfig.emptyText }}</span>
  14. </template>
  15. <TableColumn v-for="column in props.tableConfig.columns" :key="column.prop || column.label" :column="column">
  16. <template v-for="(_, name) in $slots" #[name]="slotData">
  17. <slot :name="name" v-bind="slotData" />
  18. </template>
  19. </TableColumn>
  20. </el-table>
  21. <el-pagination
  22. v-if="props.tableConfig.pagination && props.tableConfig.pagination.total > 0"
  23. :current-page="props.tableConfig.pagination.pageNumber"
  24. :page-size="props.tableConfig.pagination.pageSize"
  25. :page-sizes="props.pageSizeConfig || PAGE_SIZE_CONFIG"
  26. :layout="DEFAULT_PAGINATION_LAYOUT"
  27. background
  28. :total="props.tableConfig.pagination.total"
  29. @size-change="handleSizeChange"
  30. @current-change="handleCurrentChange"
  31. />
  32. </div>
  33. </template>
  34. <script lang="ts" setup>
  35. import { ref } from 'vue';
  36. import TableColumn from './TableColumn.vue';
  37. import type { ElTable } from 'element-plus';
  38. import type { BasicTableProps } from '@/types/basic-table';
  39. import { PAGE_SIZE_CONFIG, DEFAULT_PAGINATION_LAYOUT } from '@/constant/pagination';
  40. import EmptyImg from 'assets/images/empty@1X.png';
  41. const selectedIds = ref<number[]>([]);
  42. const tableRef = ref<InstanceType<typeof ElTable>>();
  43. const props = defineProps<{
  44. tableConfig: BasicTableProps;
  45. tableData: any[];
  46. pageSizeConfig?: number[];
  47. }>();
  48. const emits = defineEmits<{
  49. (e: 'update:pageSize', value: number): void;
  50. (e: 'update:pageNumber', value: number): void;
  51. (e: 'update:selection', value: any[]): void;
  52. }>();
  53. const handleSizeChange = (value: number) => {
  54. emits('update:pageSize', value);
  55. };
  56. const handleCurrentChange = (value: number) => {
  57. emits('update:pageNumber', value);
  58. };
  59. const handleSelectionChange = (selection: any[]) => {
  60. selectedIds.value = selection.map((item) => item.id);
  61. emits('update:selection', selection);
  62. };
  63. const clearSelection = () => {
  64. if (!tableRef.value) return;
  65. tableRef.value.clearSelection();
  66. selectedIds.value = [];
  67. emits('update:selection', []);
  68. };
  69. defineExpose({
  70. selectedIds,
  71. clearSelection,
  72. });
  73. </script>
  74. <style lang="scss" scoped>
  75. .basic-table {
  76. display: flex;
  77. flex-direction: column;
  78. justify-content: space-between;
  79. width: 100%;
  80. height: 100%;
  81. }
  82. .el-table {
  83. width: 100%;
  84. }
  85. .el-pagination {
  86. display: flex;
  87. justify-content: flex-end;
  88. }
  89. :deep(.el-loading-mask) {
  90. background-color: rgba(0, 0, 0, 0.05);
  91. }
  92. :deep(.el-table__empty-text) {
  93. @include flex-center;
  94. flex-direction: column;
  95. padding-top: 20px;
  96. img {
  97. width: 510px;
  98. }
  99. }
  100. :deep(.el-table__empty-block) {
  101. height: calc(100vh - 450px) !important;
  102. }
  103. </style>