Table.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <template>
  2. <div class="page_table">
  3. <el-table
  4. :height="height"
  5. class="el-table--border"
  6. ref="tableRef"
  7. :show-header="showHeader"
  8. :data="tableData"
  9. stripe
  10. v-loading="loading"
  11. element-loading-text="拼命加载中……"
  12. element-loading-spinner="el-icon-loading"
  13. element-loading-background="#ffffff"
  14. element-loading-custom-class="loading_icon"
  15. :row-class-name="tableRowClassName"
  16. @row-click="(row, column) => $emit('rowClick', row)"
  17. :span-method="spanMethod"
  18. >
  19. <template v-for="(item, index) in tableColumns">
  20. <el-table-column
  21. :key="item?.name"
  22. v-if="!item.hidden"
  23. :prop="item.name"
  24. :min-width="item.minWidth"
  25. :width="item.width"
  26. :label="item.label"
  27. :fixed="item.fixed ? item.fixed : false"
  28. :align="item.align"
  29. >
  30. <template v-if="item.customHeader" v-slot:header>
  31. <slot :name="'header-' + item.name"></slot>
  32. </template>
  33. <template v-if="item.custom" v-slot:default="row">
  34. <slot :name="item.name" :row="row.row" :currentIndex="(row.$index + 1)"></slot>
  35. </template>
  36. </el-table-column>
  37. </template>
  38. </el-table>
  39. <div class="page_pagination" v-if="!hidePagination">
  40. <slot name="paginationDesc"></slot>
  41. <el-pagination
  42. :hide-on-single-page="hidesinglePage"
  43. :current-page="currentPage"
  44. :page-size="pageSize"
  45. :page-sizes="[20, 50, 100]"
  46. background
  47. :layout="(showPageSize ? 'sizes,' : '') + 'prev, pager, next'"
  48. :total="Number(totalNum)"
  49. @current-change="(val) => $emit('paginationChange', { type: 'currentPage', val })"
  50. @size-change="(val) => $emit('paginationChange', { type: 'pageSize', val })"
  51. />
  52. </div>
  53. </div>
  54. </template>
  55. <script>
  56. /*
  57. interface tableColumnItm {
  58. name:String,
  59. label:String,
  60. width?:String,
  61. fixed?:String,
  62. align?:String,
  63. minWidth?:String,
  64. custom:Boolean,
  65. customHeader?:Boolean,
  66. hidden:Boolean,
  67. }
  68. */
  69. export default {
  70. name: 'Table',
  71. props: {
  72. tableData: {
  73. type: Array,
  74. required: true
  75. },
  76. tableColumns: {
  77. type: Array, //类型为 tableColumnItm[]
  78. required: true
  79. },
  80. currentPage: {
  81. type: Number,
  82. default: 1
  83. },
  84. showPageSize:{
  85. type:Boolean,
  86. default:false
  87. },
  88. pageSize: {
  89. type: Number,
  90. default: 20
  91. },
  92. totalNum: {
  93. type: Number,
  94. default: 0
  95. },
  96. loading: {
  97. type: Boolean,
  98. default: false
  99. },
  100. hidesinglePage: {
  101. type: Boolean
  102. },
  103. hidePagination: {
  104. type: Boolean,
  105. default: false
  106. },
  107. spanMethod: {
  108. type: Function,
  109. required: false
  110. },
  111. tableRowClassName: {
  112. type: Function,
  113. required: false
  114. },
  115. showHeader: {
  116. type: Boolean,
  117. default: true
  118. },
  119. height:{
  120. type:String,
  121. default:'calc(100%)'
  122. }
  123. },
  124. data() {
  125. return {
  126. // Vue 2 中没有 defineModel,tableRef 仅作为内部状态或普通 ref
  127. // 父组件获取表格实例请使用 this.$refs.tableRef
  128. tableRef: null
  129. };
  130. },
  131. mounted(){
  132. /*
  133. //demo
  134. HandleSpanMethod({row,column,rowIndex,columnIndex}){
  135. if(['type'].includes(column.property)){
  136. return {
  137. rowspan: row.sameRow,
  138. colspan: 1,
  139. }
  140. }
  141. }
  142. HandleTableRowClassName({row,rowIndex}){
  143. if(row.parentIndex % 2 == 0){
  144. // 偶数行
  145. return 'even_row'
  146. }else{
  147. // 奇数行
  148. return 'odd_row'
  149. }
  150. }
  151. */
  152. }
  153. };
  154. </script>
  155. <style lang="scss" scoped>
  156. .page_table {
  157. // flex-shrink: 0;
  158. // overflow: auto;
  159. display: flex;
  160. flex-direction: column;
  161. justify-content: flex-start;
  162. ::v-deep .el-table {
  163. tr th.el-table__cell {
  164. font-size: 14px;
  165. }
  166. .el-table__body-wrapper{
  167. overflow: auto;
  168. }
  169. }
  170. .el-table {
  171. flex-grow: 1;
  172. ::v-deep .el-scrollbar__view {
  173. height: 100%;
  174. }
  175. }
  176. ::v-deep .el-table__body {
  177. tbody tr.even_row td {
  178. background-color: white;
  179. }
  180. tbody tr.odd_row td {
  181. background-color: rgb(250, 250, 250);
  182. }
  183. tbody tr.hover-row td {
  184. background-color: rgb(245, 247, 250) !important;
  185. }
  186. tbody tr td:last-child:not([rowspan="1"]) {
  187. border-left: solid rgba(235, 238, 245) 1px;
  188. }
  189. }
  190. }
  191. ::v-deep .loading_icon {
  192. .el-loading-spinner {
  193. .el-loading-text {
  194. color: #2e64fa;
  195. }
  196. }
  197. }
  198. </style>