index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <template>
  2. <mescroll-uni @init="mescrollInit" @down="downCallback" @up="upCallback" :height="height || windowHeight + 'px'"
  3. :up="{ textNoMore: '-- 没有更多了 --', auto: isUpAutoLoad }" :down="{ auto: isUpAutoLoad }">
  4. <slot></slot>
  5. </mescroll-uni>
  6. </template>
  7. <script setup>
  8. import {
  9. computed,
  10. onMounted,
  11. ref,
  12. watch,
  13. reactive
  14. } from 'vue';
  15. import {
  16. onShow
  17. } from '@dcloudio/uni-app';
  18. import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js";
  19. // 调用mescroll的hook (注: mescroll-uni不用传onPageScroll,onReachBottom, 而mescroll-body必传)
  20. const {
  21. mescrollInit,
  22. getMescroll
  23. } = useMescroll()
  24. const windowHeight = computed(() => {
  25. const sys = uni.getSystemInfoSync()
  26. return sys.windowHeight - props.diffHeight
  27. })
  28. const downCallback = (mescroll) => {
  29. mescroll.resetUpScroll()
  30. }
  31. const emit = defineEmits(['updateList', 'update:total'])
  32. const props = defineProps({
  33. request: {
  34. type: Function
  35. },
  36. requestStr: {
  37. type: String
  38. },
  39. isRefresh: {
  40. type: [Number, Boolean],
  41. default: 0
  42. },
  43. height: {
  44. type: [String, Number]
  45. },
  46. total: {
  47. type: [Number],
  48. default: 0
  49. },
  50. otherParams: {
  51. type: Object,
  52. default: () => ({})
  53. },
  54. diffHeight: {
  55. type: Number,
  56. default: 0
  57. },
  58. immediate: {
  59. type: Boolean,
  60. default: false
  61. },
  62. method: {
  63. type: String,
  64. default: 'get'
  65. },
  66. isUpAutoLoad: {
  67. type: Boolean,
  68. default: true
  69. }
  70. })
  71. const list = ref([])
  72. let loadSeq = 0
  73. const normalizeListData = (res) => {
  74. if (Array.isArray(res?.rows)) return res.rows
  75. if (Array.isArray(res?.data?.rows)) return res.data.rows
  76. if (Array.isArray(res?.data)) return res.data
  77. return []
  78. }
  79. const getList = (mescroll) => {
  80. return new Promise((resolve, reject) => {
  81. let params = {
  82. pageNum: mescroll.num,
  83. pageSize: mescroll.size,
  84. ...props.otherParams
  85. }
  86. let methods = props.method == 'post' ? uni.$u.http.post(props.requestStr, params) : uni.$u.http.get(props.requestStr, {
  87. params
  88. })
  89. methods.then(res => {
  90. emit('update:total', res.total || res.data?.total || 0)
  91. resolve(res)
  92. }).catch(reject)
  93. })
  94. }
  95. // 上拉加载的回调: 其中num:当前页 从1开始, size:每页数据条数,默认10
  96. const upCallback = (mescroll) => {
  97. if (!props.requestStr) {
  98. mescroll.endErr()
  99. return
  100. }
  101. const seq = ++loadSeq
  102. getList(mescroll).then(res => {
  103. if (seq !== loadSeq) return
  104. if (res?.code !== undefined && res.code !== 200) {
  105. mescroll.endErr()
  106. return
  107. }
  108. const curPageData = normalizeListData(res)
  109. if (mescroll.num == 1) list.value = []
  110. list.value = list.value.concat(curPageData)
  111. emit('updateList', list.value, mescroll.num)
  112. const total = res.total ?? res.data?.total ?? 0
  113. mescroll.endBySize(curPageData.length, total)
  114. }).catch(() => {
  115. if (seq !== loadSeq) return
  116. mescroll.endErr()
  117. })
  118. }
  119. //重置列表
  120. const resetUpScroll = () => {
  121. loadSeq++
  122. setTimeout(() => {
  123. const mescroll = getMescroll()
  124. if (!mescroll) return
  125. if (mescroll.isUpScrolling) {
  126. mescroll.endErr()
  127. }
  128. mescroll.resetUpScroll()
  129. }, 100)
  130. }
  131. const scroll = (e) => {
  132. emit('scroll', e)
  133. }
  134. defineExpose({
  135. resetUpScroll
  136. })
  137. </script>
  138. <style lang="scss" scoped>
  139. .item {
  140. line-height: 150rpx;
  141. border-bottom: 1px solid #ccc;
  142. }
  143. </style>