CommonTable.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <div class="tablePaganations">
  3. <a-config-provider :locale="locale">
  4. <a-table
  5. class="ant-table-striped"
  6. bordered
  7. size="small"
  8. height="1000px"
  9. :loading="isLoading"
  10. :data-source="dataSource"
  11. :columns="columns"
  12. :scroll="{ y: 350 }"
  13. :pagination="pagination"
  14. :row-key="(record) => record.id"
  15. :row-selection="
  16. isSelect
  17. ? {
  18. selectedRowKeys: state.selectedRowKeys,
  19. onSelect: selectEvent,
  20. onSelectAll: selectAllEvent,
  21. }
  22. : null
  23. "
  24. :row-class-name="
  25. (_record, index) => (index % 2 === 1 ? 'table-striped' : null)
  26. "
  27. >
  28. <template
  29. v-for="(item, index) in renderArr"
  30. #[item]="scope"
  31. :key="index"
  32. >
  33. <slot :name="item" :scope="scope" v-bind="scope || {}" />
  34. </template>
  35. </a-table>
  36. </a-config-provider>
  37. </div>
  38. </template>
  39. <script setup>
  40. import {
  41. useSlots,
  42. ref,
  43. reactive,
  44. defineProps,
  45. defineEmits,
  46. watch,
  47. onMounted,
  48. defineExpose,
  49. } from 'vue';
  50. import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN';
  51. const locale = ref(zhCN);
  52. const props = defineProps({
  53. dataSource: {
  54. type: Object,
  55. required: true,
  56. },
  57. columns: {
  58. type: Object,
  59. required: true,
  60. },
  61. isSelect: {
  62. type: Boolean,
  63. },
  64. isLoading: {
  65. type: Boolean,
  66. },
  67. total: {
  68. type: Number,
  69. default: 0,
  70. },
  71. });
  72. // 选择数据
  73. const state = reactive({
  74. selectedRows: [],
  75. selectedRowKeys: [],
  76. });
  77. // 分页配置
  78. const pagination = reactive({
  79. showQuickJumper: true,
  80. current: 1,
  81. pageSize: 20, // 默认每页显示数量
  82. showSizeChanger: true, // 显示可改变每页数量
  83. pageSizeOptions: ['20', '50', '100', '200', '300', '500'], // 每页数量选项值
  84. showTotal: (total, range) =>
  85. range[0] + '-' + range[1] + '条' + ' 共' + total + '条', // 显示总数
  86. onShowSizeChange: (current, pageSize) => showSizeChange(current, pageSize),
  87. onChange: (current, pageSize) => changePage(current, pageSize), //点击页码事件
  88. total: props.total,
  89. });
  90. const emit = defineEmits(['pageParams', 'selectColumn']);
  91. // 改变每页数量时更新显示
  92. const showSizeChange = (current, pageSize) => {
  93. setTimeout(() => {
  94. pagination.current = 1;
  95. emit('pageParams', pagination.current, pageSize);
  96. });
  97. pagination.pageSize = pageSize;
  98. };
  99. //点击页码事件
  100. const changePage = (current, size) => {
  101. pagination.current = current;
  102. emit('pageParams', pagination.current, size);
  103. };
  104. // 选择每一项操作
  105. const selectEvent = (record, selected, selectedRows) => {
  106. if (selected) {
  107. state.selectedRows.push(record);
  108. state.selectedRowKeys.push(record.id);
  109. } else {
  110. let index = state.selectedRowKeys.indexOf(record.id);
  111. if (index >= 0) {
  112. state.selectedRows.splice(index, 1);
  113. state.selectedRowKeys.splice(index, 1);
  114. }
  115. }
  116. emit('selectColumn', state.selectedRows);
  117. };
  118. // 全选按钮操作
  119. const selectAllEvent = (selected, selectedRows, changeRows) => {
  120. if (selected) {
  121. state.selectedRows = state.selectedRows.concat(changeRows);
  122. state.selectedRows.forEach(item => {
  123. state.selectedRowKeys.push(item.id);
  124. });
  125. } else {
  126. changeRows.forEach(item => {
  127. state.selectedRows.forEach(row => {
  128. if (item.id == row.id) {
  129. state.selectedRows.splice(0, 1);
  130. }
  131. });
  132. let index = state.selectedRowKeys.indexOf(item.id);
  133. if (index >= 0) {
  134. state.selectedRows.splice(index, 1);
  135. state.selectedRowKeys.splice(index, 1);
  136. }
  137. });
  138. }
  139. emit('selectColumn', state.selectedRows);
  140. };
  141. // 清空选择
  142. const clear = () => {
  143. state.selectedRowKeys = [];
  144. state.selectedRows = [];
  145. emit('selectColumn', state.selectedRows);
  146. };
  147. // 回到第一页
  148. const backFirstPage = () => {
  149. pagination.current = 1;
  150. emit('pageParams', pagination.current,pagination.pageSize);
  151. };
  152. defineExpose({ clear,backFirstPage });
  153. // 监听total变化
  154. watch(
  155. props,
  156. newData => {
  157. pagination.total = newData.total;
  158. },
  159. { immediate: true, deep: true },
  160. );
  161. // 插槽的实例
  162. const slots = useSlots();
  163. const renderArr = Object.keys(slots);
  164. </script>
  165. <style scoped>
  166. .tablePaganations {
  167. width: 100%;
  168. margin-top: 20px;
  169. margin-bottom: 20px;
  170. }
  171. .ant-table-striped :deep(.table-striped) td {
  172. background-color: #fafafa;
  173. }
  174. </style>