【前言】html
使用vue處理項目中遇到列表頁面時,有一些細節須要注意,這裏總結一下,以便優化之後的代碼。以下:vue
1. 使用mint-ui中的LoadMore組件上下拉刷新時,有時沒法觸發上拉加載更多的方法。還有ios上滾動不太流暢。ios
2. 從列表進入詳情(列表數據分頁請求的),再返回時,列表頁須要記住以前的滾動位置,記住它上次的數據,但從其餘頁面進入列表頁時,須要它從新刷新。(ps: 好像後面的vue版本對keepAlive頁面滾動條會自動記錄並處理)git
【須要實現效果】github
本demo將實現以下效果。web
【實現思路】vuex
1. 使用 mint-ui 中 LoadMore 組件,定時器延時模擬上下拉刷新。緩存
2. 將B頁的 keepAlive 設置爲true,在這個頁面的路由鉤子方法中判斷是從哪一個頁面進入到的列表頁,若是是從C頁返回,那麼就讓B不刷新數據;從其餘頁面進來就讓B刷新數據。這樣能夠實現 A -> B -> C過程當中,若是 C -> B,那麼B保持不變,其餘頁面進入B將從新刷新數據,這就像原生應用頁面跳轉了。app
【須要處理的細節】函數
1. mint-ui中loadMore組件一些使用注意。
2. activated中根據不一樣頁面刷新數據。
3. 使用vuex存儲b頁面進入c頁面時的滾動條位置。
【相關代碼】
1. mint-ui中loadmore組件須要對它外層包裹一層,且它的高度要進行設定,否則它的滑動會出現問題(有時沒法觸發加載更多方法,有時還沒滑到底部就開始觸發加載更多的方法)。以下:
<div class="content" :style="{height: contentH + 'px'}" ref="wrapper" @scroll="scrollEvent()"> <Loadmore class="LoadMore" :top-method="loadTop" :bottom-method="loadBottom" ref="loadmore"> <div class="item" v-for="(index, elem) in dataArray" @click="itemClick(index, elem)"> <p class="itemP">item_{{index}}</p> </div> </Loadmore> </div>
而後對 contentH 變量的賦值以下
mounted() { // mint-ui loadmore組件須要包裹,且內容高度要高於包裹纔可加載更多,因此這時給包裹層 一個指定的高度 this.contentH = document.documentElement.clientHeight - this.$refs.wrapper.getBoundingClientRect().top; }
模擬上下拉刷新以下:
// 下拉刷新 loadTop() { let that = this; setTimeout(function() { that.dataArray = [0, 1, 2, 3, 4, 5]; that.$refs.loadmore.onTopLoaded(); }, 1500); }, // 上拉加載更多 loadBottom() { let that = this; setTimeout(function() { let tempArray = []; let lastItem = that.dataArray[that.dataArray.length - 1]; for (let i = 0; i < 6; i ++) { that.dataArray.push(i + lastItem + 1); } that.$refs.loadmore.onBottomLoaded(); }, 1500); }
2. 在 B 的路由鉤子中用變量記錄來自哪一個頁面。
beforeRouteEnter(to, from, next) { if (from.name != 'C') { isFromC = false; } else { isFromC = true; } next(); }
3. vuex中記錄 B 頁面滾動條位置
const state = { pageYOffset: 0 } const mutations = { setPageYOffset(state, val) { state.pageYOffset = val; } } export default new Vuex.Store({ state, mutations })
4. 進入C頁面前,保存滾動條位置
itemClick(item, index) { // 進入C頁面 // 保存滾動條位置 this.$store.commit('setPageYOffset', this.$refs.wrapper.scrollTop); this.$router.push({ name: 'C', params: { item: item, index: index } }); }
5. 在activated方法中處理滾動條位置及數據初始化。
activated() { if (isFromC) { // 來自C頁面 this.$refs.wrapper.scrollTop = this.$store.state.pageYOffset; } else { // 滾動到最頂,數據初始化 this.$refs.wrapper.scrollTop = 0; this.dataArray = [0, 1, 2, 3, 4, 5]; } }
6. 在ios上滑動不流暢樣式設置處理,即 -webkit-overflow-scrolling: touch
.content { margin-top: 49px; overflow-y: scroll; -webkit-overflow-scrolling: touch; }
【延伸】
利用路由的keepAlive,還能夠處理其餘更復雜的頁面緩存,能夠緩存頁面臨時性的信息,再經過路由的鉤子函數處理數據清除的邏輯。這樣就不再擔憂單頁應用中由於頁面跳來跳去的數據處理了。便可以模擬相似原生app中頁面push和pop時的數據狀態變化。
【demo地址】
https://github.com/LiJinShi/vue_keepAlive