scroll.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <template>
  2. <div ref="scrollWrapper" class="scroll-wrapper">
  3. <div ref="scrollContent" class="scroll-content">
  4. <!-- 这里放置你的内容,例如下拉刷新和上拉加载的内容 -->
  5. <!-- 下拉刷新区域 -->
  6. <div v-if="pullupDown" class="refresh-wrapper">
  7. {{ refreshText }}
  8. </div>
  9. <!-- 内容区域 -->
  10. <div class="list-content">
  11. <slot></slot>
  12. </div>
  13. <!-- 上拉加载更多区域 -->
  14. <div v-if="showLoadMoreText" class="load-more-wrapper">
  15. <div class="load-more-indicator">
  16. {{ loadMoreText }}
  17. </div>
  18. </div>
  19. </div>
  20. </div>
  21. </template>
  22. <script>
  23. import BScroll from 'better-scroll';
  24. export default {
  25. props: {
  26. //开启下拉刷新
  27. pullupDown: {
  28. type: Boolean,
  29. default: true,
  30. },
  31. //开启上拉加载更多
  32. pullup: {
  33. type: Boolean,
  34. default: true,
  35. },
  36. //下拉刷新回调函数
  37. pullupDownFn: {
  38. type: Function,
  39. default: () => {},
  40. },
  41. //上拉加载更多回调函数
  42. pullupFn: {
  43. type: Function,
  44. default: () => {},
  45. },
  46. },
  47. data() {
  48. return {
  49. bs: null, // better-scroll 实例
  50. isRefreshing: false, // 是否正在刷新
  51. isLoadingMore: false, // 是否正在加载更多
  52. showLoadMoreText: false, // 是否显示加载更多
  53. refreshText: '下拉刷新', // 刷新文本
  54. loadMoreText: '加载更多', // 加载更多文本
  55. pullupUp: true, // 是否可以上拉加载更多
  56. };
  57. },
  58. mounted() {
  59. // 初始化 better-scroll
  60. this.initScroll();
  61. },
  62. watch: {
  63. pullup: {
  64. handler(val) {
  65. console.log('状态改变',val)
  66. this.pullupUp = val
  67. },
  68. immediate: true
  69. },
  70. },
  71. methods: {
  72. /** 刷新滚动容器高度,使用时最好在nextTick函数中调用*/
  73. refresh() {
  74. // this.$nextTick(()=>{
  75. // console.log('刷新滚动容器')
  76. // this.bs.finishPullUp(); // 加载更多完成
  77. // this.bs.refresh(); // 重新计算高度
  78. // })
  79. setTimeout(() => {
  80. console.log('刷新滚动容器')
  81. this.bs.finishPullUp(); // 加载更多完成
  82. this.bs.refresh();
  83. },500)
  84. },
  85. // 初始化 better-scroll
  86. initScroll() {
  87. let el = this.$refs.scrollWrapper;
  88. this.bs = new BScroll(el, {
  89. probeType: 3, // 1: 滚动时派发scroll事件 2: 滚动时派发scroll事件,每隔一定时间派发一次 3: 每隔一定时间派发scroll事件
  90. click: true, // 允许点击
  91. observeDOM: true,
  92. pullDownRefresh: {
  93. threshold: 50, // 下拉刷新的触发距离
  94. },
  95. pullUpLoad: {
  96. threshold: -50, // 上拉加载的触发距离
  97. },
  98. });
  99. console.log(this.bs,'初始化成功')
  100. // 监听下拉刷新事件
  101. this.bs.on('pullingDown', this.pullingDownHandler);
  102. // 监听上拉加载事件
  103. this.bs.on('pullingUp', this.pullingUpHandier);
  104. // better-scroll 初始化完成后,刷新 scroll
  105. this.$nextTick(()=>{
  106. this.bs.refresh();
  107. })
  108. },
  109. // 下拉刷新
  110. async pullingDownHandler(){
  111. console.log('下拉刷新')
  112. if(this.pullupDown) {
  113. this.isRefreshing = true;
  114. //this.refreshText = '正在刷新';
  115. this.$emit('refresh');
  116. // 这里可以执行刷新操作,例如发送请求获取数据
  117. await this.downFn();
  118. // 刷新完成后,调用 this.refreshFinish() 结束刷新
  119. setTimeout(() => {
  120. this.refreshFinish();
  121. }, 500);
  122. }else {
  123. setTimeout(() => {
  124. this.refreshFinish();
  125. }, 300);
  126. }
  127. },
  128. // 上拉加载
  129. async pullingUpHandier(){
  130. console.log(this.pullupUp,'pullingUp2')
  131. if(this.pullupUp) {
  132. this.showLoadMoreText = true;
  133. this.loadMoreText = '正在加载...';
  134. this.$emit('loadMore');
  135. await this.upFn();
  136. this.loadMoreText = '加载更多';
  137. this.showLoadMoreText = false;
  138. // 加载完成后,调用 this.loadMoreFinish() 结束加载更多
  139. }else {
  140. setTimeout(() => {
  141. this.loadMoreFinish();
  142. }, 300);
  143. }
  144. },
  145. async downFn(){
  146. await this.pullupDownFn();
  147. },
  148. async upFn(){
  149. await this.pullupFn();
  150. },
  151. // 结束下拉刷新
  152. refreshFinish() {
  153. console.log('更新容器高度');
  154. this.refreshText = '下拉刷新';
  155. this.bs.finishPullDown(); // 刷新完成
  156. this.bs.refresh(); // 重新计算高度
  157. },
  158. // 结束上拉加载更多
  159. loadMoreFinish() {
  160. this.loadMoreText = '加载更多';
  161. this.showLoadMoreText = false;
  162. },
  163. },
  164. beforeDestroy() {
  165. // 销毁 better-scroll
  166. this.bs.destroy();
  167. this.bs = null;
  168. console.log(this.bs,'销毁')
  169. },
  170. // destroyed() {
  171. // // 销毁 better-scroll
  172. // this.bs.destroy();
  173. // this.bs = null;
  174. // console.log(this.bs,'销毁')
  175. // },
  176. };
  177. </script>
  178. <style lang="scss" scoped>
  179. .scroll-wrapper {
  180. position: relative;
  181. overflow: hidden;
  182. width: 100%;
  183. height: 100%;
  184. }
  185. .scroll-content {
  186. position: absolute;
  187. width: 100%;
  188. }
  189. .refresh-wrapper {
  190. position: absolute;
  191. top: -80px;
  192. display: flex;
  193. width: 100%;
  194. justify-content: center;
  195. align-items: center;
  196. text-align: center;
  197. height: 80px;
  198. line-height: 80px;
  199. font-size: 28px;
  200. color: #666;
  201. }
  202. .load-more-wrapper {
  203. text-align: center;
  204. height: 80px;
  205. line-height: 80px;
  206. font-size: 28px;
  207. color: #666;
  208. }
  209. </style>