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组件库,大厂产品还是比较靠谱些,上拉加载、下滑刷新这些用起来都比较简单,效果也不错。
个人原创博客,转载请注明来源地址:https://www.cnblogs.com/xyyt
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通