因为element Plus和element UI目前都不支持表格的无限下拉滚动,所以如果想要实现,就需要自己去写自定义指令来实现,在功能实现的探索过程中,我也尝试了使用引入插件来实现,但是发现目前针对elemtnt Plus来实现的插件似乎还没有
以下是实现的具体代码:
在table中添加自定义指令
<el-table
v-loadMore.expand="{func: loadmore, target: '.el-scrollbar__wrap', delay: 300}"
:load-more-disabled="false"
></el-table>
<script lang="ts" setup>
const loadmore = () => {}
</script>
添加自定义指令directive文件
import type { Directive, App } from 'vue';
const debounce = function (func: any, delay: any) {
let timer: any = null
return function () {
if (timer) clearTimeout(timer)
timer = null
let self = this
let args = arguments
timer = setTimeout(() => {
func.apply(self, args)
}, delay)
}
}
const loadMore: Directive = {
mounted (el: any, binding: any, vnode: any) {
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 = function () {
const { scrollTop, scrollHeight, clientHeight } = targetEl
let disabled = el.getAttribute('load-more-disabled')
disabled = vnode[disabled] || disabled
if (scrollHeight <= scrollTop + clientHeight + distance) {
if (disabled == 'true') return
func && func()
}
}
targetEl.addEventListener('scroll', binding.handler)
} else {
binding.handler = debounce(function () {
const { scrollTop, scrollHeight, clientHeight } = el
if (scrollHeight === scrollTop + clientHeight) {
binding.value && binding.value()
}
}, 200)
el.addEventListener('scroll', binding.handler)
}
},
unmounted (el: any, binding: any) {
let { arg } = binding
// 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
if (arg === 'expand') {
/**
* target 目标DOM节点的类名
* offset 触发加载的距离阈值,单位为px
* method 触发的方法
* delay 防抖时延,单位为ms
*/
const { target } = binding.value
if (typeof target !== 'string') return
let targetEl = el.querySelector(target)
targetEl && targetEl.removeEventListener('scroll', binding.handler)
targetEl = null
} else {
el.removeEventListener('scroll', binding.handler)
el = null
}
}
};
export function setupLoadMoreDirective(app: App) {
app.directive('loadMore', loadMore);
}
export default loadMore;
directive文件夹下的index文件引入
import type { App } from 'vue';
import { setupLoadMoreDirective } from './loadMore';
export function setupGlobDirectives(app: App) {
setupLoadMoreDirective(app)
}
main.ts文件全局初始化
import { setupGlobDirectives } from '@/directives';
function init(){
const app = createApp(App);
setupGlobDirectives(app);
}
init()