index.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <template>
  2. <!-- 列表 -->
  3. <scroll-view class="scroll-view" scroll-y refresher-enabled :refresher-triggered="isRefreshing"
  4. @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
  5. <!-- 空状态 -->
  6. <view v-if="!loading && !dataList.length" class="empty-state">
  7. <view class="flex-d flex-a-c" style="padding-top: 25vh;" v-if="slotEmpty">
  8. <image src="@/pages-home/static/no-data.png" style="width:100%;height:260rpx" mode="heightFix"></image>
  9. <view class="common-title" style="padding:33rpx 0 20rpx 0">暂无内容</view>
  10. <view class="common-text" v-if="emptyText">{{ emptyText }}</view>
  11. </view>
  12. <u-empty v-else mode="list" text="暂无扫描记录" margin-top="200"></u-empty>
  13. </view>
  14. <slot></slot>
  15. <!-- 加载更多 -->
  16. <view class="load-more" v-if="dataList.length > 0">
  17. <u-divider :bg-color="bgColor">{{ hasMore ? '加载中...' : '我是有底线的' }}</u-divider>
  18. </view>
  19. </scroll-view>
  20. </template>
  21. <script>
  22. export default {
  23. data() {
  24. return {
  25. isRefreshing: false,
  26. loading: false,
  27. page: 1,
  28. hasMore: true,
  29. dataList: [],
  30. }
  31. },
  32. props: {
  33. bgColor: {
  34. type: String,
  35. default: '#F5F5F5'
  36. },
  37. url: {
  38. type: String,
  39. required: true,
  40. default: '/token/order/scanLogs'
  41. },
  42. pageSize: {
  43. type: Number,
  44. default: 10
  45. },
  46. slotEmpty: {
  47. type: Boolean,
  48. default: false
  49. },
  50. emptyText: {
  51. type: String,
  52. },
  53. params: {
  54. type: Object,
  55. default: {}
  56. },
  57. immediate: {
  58. type: Boolean,
  59. default: true
  60. }
  61. },
  62. mounted() {
  63. console.log(this.immediate, 'immediate')
  64. if (this.immediate) {
  65. this.loadData(true)
  66. }
  67. },
  68. methods: {
  69. // 加载数据
  70. async loadData(isRefresh = false, params = {}) {
  71. if (isRefresh) {
  72. this.page = 1
  73. this.hasMore = true
  74. }
  75. if (!this.hasMore || this.loading) return
  76. this.loading = true
  77. try {
  78. const res = await this.fetchBookList(params)
  79. if (isRefresh) {
  80. this.dataList = res.list
  81. } else {
  82. this.dataList = [...this.dataList, ...res.list]
  83. }
  84. this.$emit('updateList', this.dataList)
  85. this.hasMore = res.hasMore
  86. this.page++
  87. } catch (error) {
  88. uni.showToast({
  89. title: '加载失败',
  90. icon: 'none'
  91. })
  92. } finally {
  93. this.loading = false
  94. if (isRefresh) {
  95. this.isRefreshing = false
  96. }
  97. }
  98. },
  99. // 模拟获取数据
  100. fetchBookList(params = {}) {
  101. return new Promise((resolve) => {
  102. uni.showLoading({
  103. title: '加载中...',
  104. })
  105. uni.$u.http.get(this.url, {
  106. pageSize: this.pageSize,
  107. pageNum: this.page,
  108. ...params
  109. }).then(res => {
  110. resolve({
  111. list: res.rows,
  112. hasMore: res.rows ? res.rows.length < res.total - this.dataList
  113. .length : false
  114. })
  115. }).finally(() => {
  116. uni.hideLoading()
  117. })
  118. })
  119. },
  120. reloadData() {
  121. this.page = 1
  122. this.fetchBookList()
  123. },
  124. // 下拉刷新
  125. async onRefresh() {
  126. if (this.loading) return
  127. this.isRefreshing = true
  128. await this.loadData(true, this.params)
  129. },
  130. // 上拉加载更多
  131. async onLoadMore() {
  132. if (this.loading || !this.hasMore) return
  133. await this.loadData(false, this.params)
  134. },
  135. }
  136. }
  137. </script>
  138. <style lang="scss">
  139. .scroll-view {
  140. height: calc(100vh - 88rpx);
  141. }
  142. .load-more {
  143. width: 100%;
  144. display: flex;
  145. color: #999999;
  146. font-size: 24rpx;
  147. padding: 30rpx 0;
  148. justify-content: center;
  149. padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
  150. }
  151. </style>