index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <scroll-view class="custom-table" scroll-y="true" @scrolltolower="handleScrollLower">
  3. <uni-table
  4. ref="tableRef"
  5. :border="border"
  6. :stripe="stripe"
  7. :emptyText="emptyText"
  8. :loading="loading"
  9. :type="type"
  10. @selection-change="handleSelectionChange"
  11. >
  12. <!-- 表头 -->
  13. <uni-tr>
  14. <!-- 多选列 -->
  15. <uni-th
  16. v-if="type === 'selection'"
  17. type="selection"
  18. width="60"
  19. ></uni-th>
  20. <!-- 序号列 -->
  21. <uni-th
  22. v-else-if="type === 'index'"
  23. type="index"
  24. :index="index"
  25. width="60"
  26. ></uni-th>
  27. <!-- 常规列 -->
  28. <uni-th
  29. v-for="(column, index) in columns"
  30. :key="'header-' + index"
  31. :width="column.width"
  32. :align="column.align"
  33. :sortable="column.sortable"
  34. :sort-method="column.sortMethod"
  35. :sort-by="column.sortBy"
  36. :resizable="column.resizable"
  37. >
  38. <view>
  39. <span v-if="column.isRequire" class="custom-table__require">*</span>
  40. <span>{{ column.label }}</span>
  41. </view>
  42. </uni-th>
  43. </uni-tr>
  44. <!-- 表格内容 -->
  45. <uni-tr
  46. v-for="(row, rowIndex) in tableData"
  47. :key="'row-' + rowIndex"
  48. >
  49. <!-- 多选列 -->
  50. <uni-td v-if="type === 'selection'" type="selection"></uni-td>
  51. <!-- 序号列 -->
  52. <uni-td v-else-if="type === 'index'" type="index"></uni-td>
  53. <!-- 常规列 -->
  54. <uni-td
  55. v-for="(column, colIndex) in columns"
  56. :key="'cell-' + rowIndex + '-' + colIndex"
  57. :align="column.align"
  58. :width="column.width"
  59. >
  60. <!-- 自定义单元格内容 -->
  61. <slot
  62. :name="'cell-' + column.prop"
  63. :row="row"
  64. :rowIndex="rowIndex"
  65. :column="column"
  66. :colIndex="colIndex"
  67. >
  68. <!-- 默认显示 -->
  69. <template v-if="column.formatter">
  70. {{ column.formatter(row, column, row[column.prop], rowIndex) }}
  71. </template>
  72. <template v-else>
  73. {{ row[column.prop] || '-' }}
  74. </template>
  75. </slot>
  76. </uni-td>
  77. </uni-tr>
  78. </uni-table>
  79. <!-- 加载更多 -->
  80. <view v-if="loading && !$attrs.loading" class="custom-table__load-more">
  81. <u-loading-icon size="18"></u-loading-icon>
  82. <span class="custom-table__load-more-text">加载中...</span>
  83. </view>
  84. </scroll-view>
  85. </template>
  86. <script>
  87. export default {
  88. name: 'CustomTable',
  89. props: {
  90. tableData: {
  91. type: Array,
  92. default: () => []
  93. },
  94. columns: {
  95. type: Array,
  96. default: () => [],
  97. validator: (value) => {
  98. return value.every(item => item.prop && item.label);
  99. }
  100. },
  101. // 是否显示加载中
  102. loading: {
  103. type: Boolean,
  104. default: false
  105. },
  106. // 是否带有纵向边框
  107. border: {
  108. type: Boolean,
  109. default: true
  110. },
  111. // 是否显示斑马线
  112. stripe: {
  113. type: Boolean,
  114. default: false
  115. },
  116. // 表格类型 selection:多选 index:序号
  117. type: {
  118. type: String,
  119. default: '',
  120. validator: (value) => {
  121. return ['', 'selection', 'index'].includes(value);
  122. }
  123. },
  124. // 空数据显示的文本
  125. emptyText: {
  126. type: String,
  127. default: '暂无数据'
  128. },
  129. // 序号起始值
  130. index: {
  131. type: Number,
  132. default: 1
  133. }
  134. },
  135. data() {
  136. return {
  137. scrollPosition: 0 // 滚动位置
  138. };
  139. },
  140. methods: {
  141. // 滚动事件
  142. handleScrollLower(e) {
  143. this.$emit('loadMore');
  144. },
  145. // 选择项变化
  146. handleSelectionChange(e) {
  147. this.$emit('selectionChange', e.detail);
  148. }
  149. }
  150. };
  151. </script>
  152. <style lang="scss" scoped>
  153. @import './index.scss';
  154. </style>