vue-使用keepAlive對上下拉刷新列表數據 和 滾動位置細節進行處理

【前言】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

 

原文:http://www.javashuo.com/article/p-pzhgycnb-eg.html

相關文章
相關標籤/搜索