vue+Better-scroll实现滚动位置保持并对页面切换效果进行优化

前言:

环境限制,只能用hash模式,所以不能直接用vue自身的页面缓存。

如果要保持页面滚动位置,可以在页面滚动结束后将滚动距离保存到缓存中,然后在下次加载页面的时候自动滚动指定距离。

这里以Better-scroll2.0为例进行说明。

示例代码:

  1 <template>
  2   <div class="page w100 h100">
  3     <!--数据列表容器-->
  4     <div class="h100 wrapper pRelative" ref="wrapper">
  5       <div class="content pRelative">
  6         <router-link class="item lh30 w100" v-for="(item,index) in list" :key="index" :to="{name:'GoodDetail'}">
  7           <div class="iblock w30"><img :src="item.img" /></div>
  8           <div class="goodInfo w70 tl">
  9             <p class="ellipsis w90 f15">{{item.title}}</p>
 10             <p class="ellipsis_mul w90 f13 lh15">{{item.desc}}</p>
 11           </div>
 12         </router-link>
 13       </div>
 14     </div>
 15     <!--数据列表容器 end-->
 16     <!--页面切换蒙层-->
 17     <div v-show="showWhiteBoard==1" class="pAbsolute w100 h100 bgWhite">
 18       <van-loading type="spinner" style="margin-top:100px;" />
 19     </div>
 20     <!--页面切换蒙层 end-->
 21   </div>
 22 </template>
 23 
 24 <script>
 25   import http from '@/api/index'
 26   import BScroll from "@better-scroll/core"
 27   import {
 28     Loading
 29   } from 'vant';
 30   export default {
 31     name: "Better-Scroll",
 32     data() {
 33       return {
 34         list: '', //数据列表
 35         scroll: '', //滚动实例
 36         showWhiteBoard: '' //页面切换蒙层开关
 37       }
 38     },
 39     components: {
 40       [Loading.name]: Loading,
 41     },
 42     created() {
 43       this.init()
 44     },
 45     methods: {
 46       init() {
 47         http.getGoodsList({
 48           goodId: 1001
 49         }).then(data => {
 50           if (data && data.goodsList) {
 51             this.list = data.goodsList
 52             this.doScroll()
 53           }
 54         })
 55       },
 56       /**
 57        * 列表滚动事件处理
 58        * @param {Object} list
 59        */
 60       doScroll: function() {
 61         //添加滚动处理
 62         this.$nextTick(() => {
 63           if (!this.scroll) {
 64             this.scroll = new BScroll(this.$refs.wrapper, {
 65               preventDefault: false, //这个不能有,ios系统会受框架层滑动影响
 66               click: true
 67             })
 68 
 69             //自动滚动
 70             let scrollY = localStorage.getItem("scrollY")
 71             if (scrollY) {
 72               //显示页面切换的蒙板
 73               this.showWhiteBoard = 1
 74               //滚动指定距离
 75               this.scroll.scrollTo(0, scrollY, 300, undefined);
 76               //隐藏页面切换的蒙板
 77               setTimeout(() => {
 78                 this.showWhiteBoard = 0
 79               }, 300)
 80             }
 81 
 82             //保存滚动位置
 83             this.scroll.on("scrollEnd", poy => {
 84               let scrollY2 = poy && poy.y
 85               if (scrollY2) localStorage.setItem('scrollY', scrollY2)
 86             });
 87           } else {
 88             this.scroll.refresh()
 89             this.scroll.scrollTo(0, 0, 100, undefined)
 90           }
 91         })
 92       }
 93     }
 94   }
 95 </script>
 96 
 97 <style lang="scss" scoped>
 98   .page {
 99     $bc: #ffffff;
100     $fc: #000000;
101     overflow: hidden;
102 
103     @for $i from 0 to 30 {
104       .item:nth-child(#{$i}) {
105         background-color: $bc - $i*10;
106       }
107     }
108 
109     .item {
110       display: flex;
111       padding: 25px;
112 
113       img {
114         width: 150px;
115         height: 150px;
116       }
117 
118       .goodInfo {
119         margin-left: 20px;
120       }
121     }
122   }
123 </style>

注:例中使用了Better-scroll2.0处理页面滚动,以及页面的自动滚动。

体验优化:

BS滚动指定距离会有一个滚动过程,这样体验就比较差了,如下:

 

 

 解决这个问题,可以在页面加载处理自动滚动的时候添加一个蒙版,遮住这个滚动过程,这样页面切换就会好很多。相关代码如下:

1     <!--页面切换蒙层-->
2     <div v-show="showWhiteBoard==1" class="pAbsolute w100 h100 bgWhite">
3       <van-loading type="spinner" style="margin-top:100px;" />
4     </div>
5     <!--页面切换蒙层 end-->
 1 //自动滚动
 2 let scrollY = localStorage.getItem("scrollY") if (scrollY) {
 3     //显示页面切换的蒙板
 4     this.showWhiteBoard = 1
 5     //滚动指定距离
 6     this.scroll.scrollTo(0, scrollY, 300, undefined);
 7     //隐藏页面切换的蒙板
 8     setTimeout(() = >{
 9         this.showWhiteBoard = 0
10     },300)
11 }

如上,蒙版中使用了vant的loading,这样比空白页面更好些(如果运行环境本身对页面切换已经做了loading,那就不用了)。

关闭蒙版的时间设置为自动滚动后300ms,这个时间滚动基本上已经完成了(多次验证结果)。

优化后的效果如下:

 

如上,页面切换没有明显的页面滚动了(使用mock.js模拟数据,所以数据有更新,会有轻微滑动,真实接口数据则不会)。

后记:

Better-Scroll1.x出现ios兼容性问题,升级到2.x,也会有一些问题,处理起来还是有点麻烦的,决定弃用了。

建议使用vant组件库,大厂产品还是比较靠谱些,上拉加载、下滑刷新这些用起来都比较简单,效果也不错。

posted on 2021-02-24 15:47  逍遥云天  阅读(1137)  评论(0编辑  收藏  举报

导航