Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于vue滚动懒加载实现方案 #51

Open
Hibop opened this issue Nov 9, 2018 · 0 comments
Open

关于vue滚动懒加载实现方案 #51

Hibop opened this issue Nov 9, 2018 · 0 comments

Comments

@Hibop
Copy link
Owner

Hibop commented Nov 9, 2018

先看问题

一个下拉列表拉取上千条数据;
dashboard图表卡片无分页下拉;
==> 页面直接卡死,或者长时间白屏。非常影响体验

方法

  • 监听滚动
  • 向下滚动时往后加载数据
  • 向上滚动时往前加载数据
  • 数据有进有出
import Vue from 'vue';
  const scrollDirective = Vue.directive('scroll', {
    bind (el, binding) {
      // 获取滚动页面DOM
      let scrollPosition = 0;
      el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
        .addEventListener('scroll', function() {
          // 当前的滚动位置 减去  上一次的滚动位置
          // 如果为true则代表向上滚动,false代表向下滚动
          let flagPosition = this.scrollTop - scrollPosition > 0;
          // 记录当前的滚动位置
          scrollPosition = this.scrollTop;
          binding.value(flagPosition); // 将滚动行为告诉组件
          console.log(flagPosition ? '滚动方向:下' : '滚动方向:上');
        });
    }
  })


  Vue.use(scrollDirective);

  <el-select class="remoteSelect" v-scroll="handleScroll" v-model="value">
    <el-option :value="item.id" v-for="item in list" :key="item.id">{{item.name}}</el-option>
  </el-select>

  handleScroll(flagPosition) {
  // 收到滚动行为
    if(flagPosition) {
      this.list.push(...this.ajaxData(++this.pageIndex));
    }
  }

滚动加载已经实现。只是加载太频繁了,如果快速滚动则会同时发出多个请求后台数据,在密集一些游览器中ajax就要开发并发排队了,可见并不理想。那如何控制呢?那换种方式触发handleScroll事件,在滚动位置距离滚动页面底部一定高度时在触发,例如距页面底部只有100px时触发handleScroll事件

距离底部Npx再请求

       // 记录当前的滚动位置
        scrollPosition = this.scrollTop
        const LIMIT_BOTTOM = 100
        // 记录滚动位置距离底部的位置
        let scrollBottom = this.scrollHeight - (this.scrollTop + this.clientHeight) < LIMIT_BOTTOM
        // 如果已达到指定位置则触发
        if (scrollBottom) {
          // 将滚动行为告诉组件
          binding.value(flagToDirection)
        }

注意事项
会存在一个bug,即ajax是异步的,如果这个ajax请求花了1s才返回数据,而此时还在继续往下滚,那就会触发多个请求事件。如何避免这种情况呢? 答案是增加一个标志位,在请求前将该标志位设置为false,请求结束后设置为true。每次请求时先判断该标志位。如果为false则阻止该事件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant