Table.vue 5.3 KB

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