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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM