Open Hibop opened 5 years ago
一个下拉列表拉取上千条数据; 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再请求 ```js // 记录当前的滚动位置 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则阻止该事件。
先看问题
方法
数据有进有出
注意事项 会存在一个bug,即ajax是异步的,如果这个ajax请求花了1s才返回数据,而此时还在继续往下滚,那就会触发多个请求事件。如何避免这种情况呢? 答案是增加一个标志位,在请求前将该标志位设置为false,请求结束后设置为true。每次请求时先判断该标志位。如果为false则阻止该事件。