综合办公系统
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

sticky-scroll.vue 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->
  2. <template>
  3. <view>
  4. <!-- 菜单 (悬浮,预先隐藏)-->
  5. <me-tabs v-if="isShowSticky" v-model="tabIndex" :fixed="true" :tabs="tabs" @change="tabChange"></me-tabs>
  6. <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption" @scroll="scroll" @topclick="topClick">
  7. <!--轮播-->
  8. <swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
  9. <swiper-item>
  10. <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
  11. </swiper-item>
  12. <swiper-item>
  13. <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
  14. </swiper-item>
  15. </swiper>
  16. <view class="demo-tip">
  17. <view>每次切换菜单都刷新列表数据</view>
  18. <view>吸顶通过监听滚动条实现, 比sticky复杂, 但APP端可兼容低端机</view>
  19. </view>
  20. <!-- 菜单 (在mescroll-uni中不能使用fixed,否则iOS滚动时会抖动, 所以需在mescroll-uni之外存在一个一样的菜单) -->
  21. <view id="tabInList">
  22. <me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
  23. </view>
  24. <!-- 数据列表 -->
  25. <good-list :list="goods"></good-list>
  26. </mescroll-body>
  27. </view>
  28. </template>
  29. <script>
  30. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  31. import {apiSearch} from "@/api/mock.js"
  32. export default {
  33. mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
  34. data() {
  35. return {
  36. goods: [], // 数据列表
  37. upOption: {
  38. // 如果用mescroll-uni 则需要onScroll: true, 且需要 @scroll="scroll"; 而mescroll-body最简单只需在onPageScroll处理即可
  39. // onScroll: true // 是否监听滚动事件, 默认false (配置为true时,可@scroll="scroll"获取到滚动条位置和方向)
  40. },
  41. tabs: ['全部', '母婴', '图书'],
  42. tabIndex: 0, // tab下标
  43. navTop: null, // nav距离到顶部的距离 (如计算不准确,可直接写死某个值)
  44. isShowSticky: false // 是否悬浮
  45. }
  46. },
  47. methods: {
  48. /*下拉刷新的回调 */
  49. downCallback() {
  50. // 这里加载你想下拉刷新的数据, 比如刷新轮播数据
  51. // loadSwiper();
  52. // 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
  53. this.mescroll.resetUpScroll()
  54. },
  55. /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  56. upCallback(page) {
  57. //联网加载数据
  58. if(this.isChangeTab){
  59. this.mescroll.hideUpScroll(); // 切换菜单,不显示mescroll进度, 显示系统进度条
  60. uni.showLoading();
  61. }
  62. let keyword = this.tabs[this.tabIndex]
  63. apiSearch(page.num, page.size, keyword).then(curPageData=>{
  64. //联网成功的回调
  65. //设置列表数据
  66. if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
  67. this.goods=this.goods.concat(curPageData); //追加新数据
  68. // 数据渲染完毕再隐藏加载状态 this.$nextTick在iOS真机不触发,需改成setTimeout
  69. // this.$nextTick(()=>{
  70. setTimeout(()=>{
  71. this.mescroll.endSuccess(curPageData.length);
  72. // 设置nav到顶部的距离 (需根据自身的情况获取navTop的值, 这里放到列表数据渲染完毕之后)
  73. // 也可以放到onReady里面,或者菜单顶部的数据(轮播等)加载完毕之后..
  74. if(!this.navTop) this.setNavTop()
  75. // 保持tab悬浮,列表数据显示第一条
  76. if(this.isChangeTab){
  77. this.isChangeTab = false;
  78. uni.hideLoading();
  79. if(this.isShowSticky) this.mescroll.scrollTo(this.navTop, 0)
  80. }
  81. },20)
  82. }).catch(()=>{
  83. //联网失败, 结束加载
  84. this.mescroll.endErr();
  85. })
  86. },
  87. // 设置nav到顶部的距离 (滚动条为0, 菜单顶部的数据加载完毕获取到的navTop数值是最精确的)
  88. setNavTop(){
  89. let view = uni.createSelectorQuery().select('#tabInList');
  90. view.boundingClientRect(data => {
  91. console.log('tabInList基本信息 = ' + JSON.stringify(data));
  92. this.navTop = data.top // 到屏幕顶部的距离
  93. }).exec();
  94. },
  95. // mescroll-uni的滚动事件 (需在up配置onScroll:true才生效)
  96. // 而mescroll-body最简单只需在onPageScroll处理即可
  97. scroll(){
  98. console.log('滚动条位置 = ' + this.mescroll.getScrollTop() + ', navTop = ' + this.navTop);
  99. // 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏
  100. if (this.mescroll.getScrollTop() >= this.navTop) {
  101. this.isShowSticky = true // 显示悬浮菜单
  102. } else {
  103. this.isShowSticky = false // 隐藏悬浮菜单
  104. }
  105. },
  106. // 点击回到顶部按钮时,先隐藏悬浮菜单,避免闪动
  107. topClick(){
  108. this.isShowSticky = false
  109. },
  110. // 切换菜单
  111. tabChange () {
  112. this.isChangeTab = true;
  113. this.mescroll.resetUpScroll()
  114. }
  115. },
  116. // 使用mescroll-body最简单只需在onPageScroll处理即可
  117. onPageScroll(e){
  118. console.log('滚动条位置 = ' + e.scrollTop + ', navTop = ' + this.navTop);
  119. if (e.scrollTop >= this.navTop) {
  120. this.isShowSticky = true // 显示悬浮菜单
  121. } else {
  122. this.isShowSticky = false // 隐藏悬浮菜单
  123. }
  124. }
  125. }
  126. </script>
  127. <style>
  128. .demo-tip{
  129. padding: 18rpx;
  130. font-size: 24rpx;
  131. text-align: center;
  132. }
  133. </style>