前言:
環境限制,只能用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組件庫,大廠產品還是比較靠譜些,上拉加載、下滑刷新這些用起來都比較簡單,效果也不錯。