index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. console.log(res, 'res')
  104. const curPageData = res.rows || res.data?.rows || res.data || [] // 当前页数据
  105. if (mescroll.num == 1) list.value = []; // 第一页需手动制空列表
  106. list.value = list.value.concat(curPageData); //追加新数据
  107. emit('updateList', list.value, mescroll.num)
  108. const total = res.total ?? res.data?.total ?? 0
  109. mescroll.endBySize(curPageData.length, total)
  110. }).catch(() => {
  111. if (seq !== loadSeq) return
  112. mescroll.endErr()
  113. })
  114. }
  115. //重置列表
  116. const resetUpScroll = () => {
  117. loadSeq++
  118. setTimeout(() => {
  119. const mescroll = getMescroll()
  120. if (!mescroll) return
  121. if (mescroll.isUpScrolling) {
  122. mescroll.endErr()
  123. }
  124. mescroll.resetUpScroll()
  125. }, 100)
  126. }
  127. const scroll = (e) => {
  128. emit('scroll', e)
  129. }
  130. defineExpose({
  131. resetUpScroll
  132. })
  133. </script>
  134. <style lang="scss" scoped>
  135. .item {
  136. line-height: 150rpx;
  137. border-bottom: 1px solid #ccc;
  138. }
  139. </style>