Table.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <vxe-grid class="wrapper" v-bind="props.gridOptions" ref="gridRef" v-fullscreen>
  3. <template #form>
  4. <Search
  5. v-if="props?.searchConfig && props.searchConfig.enable && props.searchConfig?.fields && props.searchConfig?.data"
  6. :fields="props.searchConfig?.fields"
  7. :data="props.searchConfig?.data"
  8. v-bind="props.searchConfig"
  9. @reset="handleReset"
  10. @search="handleSearch"
  11. >
  12. <template #searchRight>
  13. <slot name="searchRight"></slot>
  14. </template>
  15. </Search>
  16. <!-- <IndexData />-->
  17. </template>
  18. <template #top>
  19. <div class="top">
  20. <div class="top-left" v-if="props?.toolbarConfig && props?.toolbarConfig.enable">
  21. <Toolbar :toolbarConfig="props.toolbarConfig">
  22. <slot name="toolbarLeft"></slot>
  23. </Toolbar>
  24. </div>
  25. <div class="top-right" v-if="props?.toolbarConfig && props?.toolbarConfig.enable">
  26. <a-tooltip placement="top">
  27. <template #title>
  28. <span>刷新</span>
  29. </template>
  30. <a-button type="text" size="small" @click="handleRefresh">
  31. <ReloadOutlined />
  32. </a-button>
  33. </a-tooltip>
  34. <a-tooltip placement="top" v-if="isZoom">
  35. <template #title>
  36. <span>还原</span>
  37. </template>
  38. <a-button type="text" size="small" @click="toggleFullscreen">
  39. <FullscreenExitOutlined />
  40. </a-button>
  41. </a-tooltip>
  42. <a-tooltip placement="top" v-if="!isZoom">
  43. <template #title>
  44. <span>全屏</span>
  45. </template>
  46. <a-button type="text" size="small" @click="toggleFullscreen">
  47. <FullscreenOutlined />
  48. </a-button>
  49. </a-tooltip>
  50. </div>
  51. </div>
  52. </template>
  53. <template #pager>
  54. <div class="pager" v-if="props?.pagerConfig && props.pagerConfig.enable">
  55. <Pagination :pagerConfig="props.pagerConfig" />
  56. </div>
  57. </template>
  58. <template #bottom>
  59. <slot name="bottom" />
  60. </template>
  61. <template #empty>
  62. <div class="empty">
  63. <bs-empty />
  64. </div>
  65. </template>
  66. <!-- 自定义列插槽 -->
  67. <template v-for="(name, idx) in slotCols" #[name]="scope" :key="idx">
  68. <slot :name="name" v-bind="scope || {}" />
  69. </template>
  70. </vxe-grid>
  71. </template>
  72. <script setup>
  73. import { nextTick, onMounted, ref, useSlots } from 'vue';
  74. import Search from './component/search/index.vue';
  75. import Pagination from './component/pagination/index.vue';
  76. import Toolbar from './component/toolbar/index.vue';
  77. import IndexData from './component/indexData/index.vue';
  78. import { mapValues, has, isString } from 'lodash';
  79. const props = defineProps(['gridOptions', 'searchConfig', 'pagerConfig', 'toolbarConfig', 'getGridRef', 'mounted']);
  80. const gridRef = ref(null);
  81. const isZoom = ref(false);
  82. const slotCols = ref([]);
  83. const setSlotsCols = () => {
  84. slotCols.value = [];
  85. props.gridOptions.columns.forEach((v) => {
  86. if(has(v, 'slots')) {
  87. mapValues(v.slots, (value, key) => {
  88. if(isString(value)) {
  89. slotCols.value.push(value);
  90. }
  91. })
  92. }
  93. });
  94. }
  95. const handleReset = () => {};
  96. const handleSearch = () => {};
  97. // 刷新回调
  98. const handleRefresh = () => {
  99. props.toolbarConfig.onRefresh && props.toolbarConfig.onRefresh();
  100. };
  101. onMounted(() => {
  102. setSlotsCols();
  103. nextTick(() => {
  104. props.getGridRef && props.getGridRef(gridRef.value);
  105. props.mounted && props.mounted(gridRef.value);
  106. });
  107. });
  108. const toggleFullscreen = () => {
  109. gridRef.value.zoom().then((zoom) => {
  110. isZoom.value = zoom;
  111. });
  112. };
  113. defineExpose({ gridRef });
  114. </script>
  115. <style lang="scss" scoped>
  116. .wrapper {
  117. width: 100%;
  118. height: 100%;
  119. .top {
  120. border-radius: 10px 10px 0 0;
  121. padding: 10px 20px;
  122. background: white;
  123. display: flex;
  124. align-items: center;
  125. .top-left {
  126. flex: 1;
  127. }
  128. .top-right {
  129. display: flex;
  130. justify-content: flex-end;
  131. align-items: center;
  132. }
  133. }
  134. .pager {
  135. width: 100%;
  136. display: flex;
  137. flex-direction: row;
  138. justify-content: flex-end;
  139. align-items: center;
  140. padding: 20px;
  141. :deep(.ant-select-in-form-item) {
  142. width: auto !important;
  143. }
  144. }
  145. :deep(.vxe-grid--table-container) {
  146. background: white;
  147. border-radius: 0 0 10px 10px;
  148. padding: 0 20px 20px 20px;
  149. }
  150. .empty {
  151. padding: 20px;
  152. }
  153. }
  154. </style>