index.vue 4.7 KB

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