scs-scroll-view.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <!--
  2. * @Author: jmy
  3. * @Date: 2026-01-07 12:02:41
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2026-01-07 15:02:10
  6. * @Description:
  7. -->
  8. <template>
  9. <!--
  10. scroll-view 组件内部,在uni-app/小程序中,
  11. scroll-view 会创建独立的滚动上下文,导致内部的 fixed 定位元素相对于
  12. scroll-view 容器定位,而非整个视窗,因此会随内容滚动。 -->
  13. <scroll-view @scrolltolower="loadMore" :scroll-y="isScroll" :scroll-with-animation="true"
  14. @refresherpulling="handlePulling" @refresherrefresh="handleRefresh" @refresherrestore="handleRefreshStore"
  15. @refresherabort="handleRefreshAbort" @scroll="onScroll" :refresher-enabled="refresherEnabled"
  16. :scroll-top="scrollTop" :refresher-threshold="80" :refresher-triggered="isTrigger" refresher-default-style="none"
  17. :refresher-background="refresherBackground" class="scs-scroll">
  18. <template slot="refresher">
  19. <view class="scs-scroll-refresher">
  20. {{ refresherText }}
  21. <text class="scroll-loading" :class="{ 'scroll-rotate': refresherText === '正在加载' }"></text>
  22. </view>
  23. </template>
  24. <slot name="list" />
  25. </scroll-view>
  26. </template>
  27. <script>
  28. export default {
  29. props: {
  30. isScroll: {
  31. type: Boolean,
  32. default: true,
  33. },
  34. list: {
  35. type: Array,
  36. default: () => {
  37. return [];
  38. },
  39. },
  40. refresherBackground: {
  41. type: String,
  42. default: "#FFF",
  43. },
  44. refresherEnabled: {
  45. type: Boolean,
  46. default: false,
  47. },
  48. },
  49. data() {
  50. return {
  51. isTrigger: false,
  52. scrollTop: 0,
  53. oldScrollTop: 0, //记录上次滚动位置
  54. refresherText: "下拉刷新",
  55. threshold: 15, // 设定触发显示隐藏的滚动距离阈值
  56. isShowToTop: true, //是否显示返回顶部按钮
  57. };
  58. },
  59. methods: {
  60. //返回顶部
  61. goTop(e) {
  62. //视图会发生重新渲染
  63. this.scrollTop = this.oldScrollTop;
  64. //当视图渲染结束 重新设置为0
  65. this.$nextTick(() => {
  66. this.scrollTop = 0;
  67. });
  68. },
  69. //滚动时触发
  70. onScroll(e) {
  71. this.isShowToTop = e.detail.scrollTop > 200;
  72. this.$emit("scroll");
  73. // console.log("scroll", e.detail.scrollTop);
  74. // e.detail.scrollTop 是当前滚动位置
  75. const scrollTop = e.detail.scrollTop;
  76. // 只有当滚动距离超过阈值时才触发显示隐藏
  77. if (Math.abs(scrollTop - this.oldScrollTop) > this.threshold) {
  78. // 根据滚动方向来确定是显示还是隐藏
  79. let isShow = !(scrollTop > this.oldScrollTop);
  80. this.$emit("updateIsTab", isShow);
  81. }
  82. // 记录上次滚动位置
  83. this.oldScrollTop = scrollTop;
  84. //判断是否显示返回顶部按钮
  85. this.$emit("handleScroll", scrollTop);
  86. },
  87. goTop(e) {
  88. //视图会发生重新渲染
  89. this.scrollTop = this.oldScrollTop;
  90. //当视图渲染结束 重新设置为0
  91. this.$nextTick(() => {
  92. this.scrollTop = 0;
  93. });
  94. },
  95. //滚动到底部加载更多
  96. loadMore() {
  97. this.$emit("loadMore");
  98. },
  99. //自定义下拉刷新控件被下拉
  100. handlePulling(e) {
  101. const self = this;
  102. let y = e.detail.deltaY;
  103. this.$emit("updateIsTab", true);
  104. if (y >= 80) {
  105. self.refresherText = "释放刷新";
  106. } else {
  107. self.refresherText = "下拉刷新";
  108. }
  109. },
  110. //自定义下拉刷新被触发
  111. handleRefresh() {
  112. const self = this;
  113. // self.goTop();
  114. self.$emit("onfresher");
  115. self.refresherText = "正在加载";
  116. },
  117. //自定义下拉刷新被复位
  118. handleRefreshStore() {
  119. const self = this;
  120. self.refresherText = "下拉刷新";
  121. },
  122. //自定义下拉刷新被中止
  123. handleRefreshAbort() {
  124. const self = this;
  125. self.refresherText = "下拉刷新";
  126. self.isTrigger = false;
  127. },
  128. },
  129. };
  130. </script>
  131. <style lang="less" scoped>
  132. // 隐藏scroll-view滚动条
  133. ::v-deep.scs-scroll {
  134. height: 99.9%;
  135. .uni-scroll-view::-webkit-scrollbar {
  136. width: 0;
  137. height: 0;
  138. display: none;
  139. }
  140. }
  141. ::v-deep .scs-scroll-refresher {
  142. height: 100%;
  143. width: 100vw;
  144. display: flex;
  145. align-items: center;
  146. justify-content: center;
  147. gap: 10rpx;
  148. color: #999999;
  149. font-size: 30rpx;
  150. text-align: center;
  151. }
  152. </style>