【前言】
使用vue處理項目中遇到列表頁面時,有一些細節需要注意,這里總結一下,以便優化以后的代碼。如下:
1. 使用mint-ui中的LoadMore組件上下拉刷新時,有時無法觸發上拉加載更多的方法。還有ios上滾動不太流暢。
2. 從列表進入詳情(列表數據分頁請求的),再返回時,列表頁需要記住之前的滾動位置,記住它上次的數據,但從其他頁面進入列表頁時,需要它重新刷新。(ps: 好像后面的vue版本對keepAlive頁面滾動條會自動記錄並處理)
【需要實現效果】
本demo將實現如下效果。
【實現思路】
1. 使用 mint-ui 中 LoadMore 組件,定時器延時模擬上下拉刷新。
2. 將B頁的 keepAlive 設置為true,在這個頁面的路由鈎子方法中判斷是從哪個頁面進入到的列表頁,如果是從C頁返回,那么就讓B不刷新數據;從其他頁面進來就讓B刷新數據。這樣可以實現 A -> B -> C過程中,如果 C -> B,那么B保持不變,其他頁面進入B將重新刷新數據,這就像原生應用頁面跳轉了。
【需要處理的細節】
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地址】