• vue-使用keepAlive对上下拉刷新列表数据 和 滚动位置细节进行处理


    【前言】

      使用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地址】

       https://github.com/LiJinShi/vue_keepAlive

  • 相关阅读:
    开博语
    ch8 固定宽度、流式、弹性布局
    ch8 让div居中--使用外边距
    ch8 基于浮动的布局(两列浮动布局、三列浮动布局)
    ch3 盒模型、定位
    事件类型--鼠标与滚轮事件
    事件类型-UI事件、焦点事件
    事件对象
    事件处理程序
    内存和性能--事件委托、移除事件处理程序
  • 原文地址:https://www.cnblogs.com/buerjj/p/8405443.html
Copyright © 2020-2023  润新知