element-ui的el-table表格实现无限滚动,使用自带的infinite-scroll
需要在el-tablel里实现滚动到底部加载更多数据
问题:使用element自带的无限滚动,但是实际用下来发现,指令只能作用于当前绑定的元素上,如下:
<ul class="infinite-list" v-infinite-scroll = "load" style="overflow:auto; height: 200px;">
<li v-for="(item, index) in tableData" :key="index">{{ item.name }}</li>
</ul>
对于不是真正的出现滚动条的标签,却无能为力
<el-table
border
height="400"
v-infinite-scroll="load"
:data="tableData"
>
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="150"></el-table-column>
<el-table-column prop="address" label="地址" width="240"></el-table-column>
</el-table>
标签不是真正的容器,绑定了指令,无法生效
实现
第一步:判断滚到底部
const { scrollTop, scrollHeight, clientHeight } = targetEl
if(scrollHeight === scrollTop + clientHeight) {
console.log('到底部了!')
}
简洁版:
export default {
name: 'load-more',
bind(el, binding, vnode) {
binding.handler = function(){
const {scrollTop, scrollHeight, clientHeight} = el
if (scrollHeight === scrollTop + clientHeight) {
binding.value && binding.value()
}
}
el.addEventListener('scroll', binding.handler)
},
unbind(el, binding) {
el.removeEventListener('scroll', binding.handler)
el = null
}
}
把写好的指令在组件内注册后,即可生效。
我们的指令能够支持:
- 可指定作用的元素
- 是否禁止无限加载
- 支持设置滚动到底部的偏移量
- 支持防抖
完整代码:
<template>
<div>
<el-table
border
height="400"
:data="visibleData"
:row-key="getRowKeys"
v-load-more.expand="{func: loadmore, target: '.el-table__body-wrapper', delay: 300}"
:load-more-disabled="disabledLoad"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" :reserve-selection="true" width="55"> </el-table-column>
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<div slot="append" style="text-align: center;">滚动到底部加载更多</div>
</el-table>
</div>
</template>
<script>
const debounce = function (func, delay) {
let timer = null
return function () {
if (timer) clearTimeout(timer)
timer = null
let self = this
let args = arguments
timer = setTimeout(() => {
func.apply(self, args)
}, delay)
}
}
export default {
directives: {
'load-more': {
bind (el, binding, vnode) {
const { expand } = binding.modifiers
// 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
if (expand) {
/**
* target 目标DOM节点的类名
* distance 减少触发加载的距离阈值,单位为px
* func 触发的方法
* delay 防抖时延,单位为ms
* load-more-disabled 是否禁用无限加载
*/
let { target, distance = 0, func, delay = 200 } = binding.value
if (typeof target !== 'string') return
let targetEl = el.querySelector(target)
if (!targetEl) {
console.log('找不到容器')
return
}
binding.handler =