思想
假设全部数据为initTable(数组),现在使用一个tableData(数组),tableData = initTable.slice(scorll, scorll+ displayCount),scroll表示当前滚动到的index, displayCount表示要展示的行数。把tableData设为el-table的数据源,只渲染该部分数据。通过对表格添加滚动事件监听,来动态更新scroll,并且对scroll添加watch,当scroll发生变化,就自动更新tableData。采用虚拟滑动条方式触发。
创建指令
创建文件夹el-table,在其下面创建loadmore.js
内容如下:
import Vue from 'vue' let flag = true
export default { bind(el, binding, vnode) { const { arg } = binding; const a = '<div class="content-height" style="height: 0px;"> </div>'; const divHtml = Vue.extend({ template: a }); el.children[0].appendChild(new divHtml().$mount().$el);
const sco = el.querySelector('.fictitious'); const cellHeihgt = parseInt((arg && arg[0])) || 50; sco.addEventListener('scroll', throttle(function () { binding.value(Math.floor(sco.scrollTop / cellHeihgt), Math.floor(sco.clientHeight / cellHeihgt)); }, 300));
document.addEventListener('mousewheel', function (ev) { var ev = window.event || ev; sco.scrollTop = -ev.wheelDelta*2 + sco.scrollTop; }); }, update: (el, binding) => { const { arg } = binding; const cellHeihgt = parseInt((arg && arg[0])) || 50; if (arg[0] * arg[1] > 0) { const contentHeight = el.querySelector('.content-height'); const sco = el.querySelector('.fictitious'); contentHeight.style.height = arg[0] * (arg[1] + 1) + 'px'; if (flag) { binding.value(0, Math.floor((window.innerHeight - 316) / cellHeihgt)); flag = false; } } else { flag = true; } } }
function throttle(fn, wait) { var timer = null; return function () { var context = this; var args = arguments; if (!timer) { timer = setTimeout(function () { fn.apply(context, args); timer = null; }, wait); } }; }
|
- fictitious:滑动条class
- content-height:滑动内容区
注册指令(main.js引入文件)
import loadmore from '...../el-table/loadmore'
Vue.directive('el-table-loadmore', loadmore)
|
创建滑动条外壳
在el-table的父层添加一下代码
<div style="position: relative; padding-right: 12px;" v-el-table-loadmore:[[rowHeight,initTable.length]]="loadMore"> <div style="position: absolute;right: 0;margin-top: 49px;height: calc(100vh - 316px);overflow-y: auto;width: 12px;" class="fictitious" v-show="scollShow"> </div> <el-table :key="key"></el-table> </div>
<script> function loadMore(firstIndex, countPage) { var arr = [] for (let index = firstIndex; index < this.initTable.length; index++) { const element = this.initTable[index]; if (index < firstIndex + countPage) { arr.push(element); } } this.tableData = JSON.parse(JSON.stringify(arr)); this.key = !this.key; } </script>
<style> .fictitious::-webkit-scrollbar-track-piece { background-color: #f8f8f8; }
.fictitious::-webkit-scrollbar { width: 12px; }
.fictitious::-webkit-scrollbar-thumb { background-color: #dddddd; border-radius: 100px; }
.fictitious::-webkit-scrollbar-thumb:hover { background-color: #bbb; } </style>
|
注: height: calc(100vh - 316px) 设置滑动条高度
- key:重新渲染表格
- rowHeight: 表示每行的高度
- initTable: 全部数据
- loadMore: 滑动触发方法 (参数1:开始展示行,参数2:展示的条数)
- scollShow:显示滚动条否