vue3+ts+elementPlus
根据产品需求,需要在弹窗中使用elementPlus的table组件。数据量少的时候没有问题,当数据条数超过30条时,会有卡顿现象。于是使用了下拉加载分页数据解决当前问题
弹窗组件中table组件代码
图中标出的是给table组件绑定了滚动监听指令:
vTablescroll
,因为组件本身没有提供监听滚动的事件;
在main.ts
中全局绑定自定义指令:.el-scrollbar_wrap
是table 的内容滚动的类名,无需自定义。
import App from '/App.vue'
const app = createApp(App)
app.directive( 'vTablescroll', {
mounted(el: Element,binding) {
const selectwrap = el.querySelector('.el-scrollbar_wrap')
if (selectWrap == null) return
selectwrap.scrollFn = function () {
const sign = 0
const scrollDistance =
this.scrollHeight - this.scrollTop - this.clientHeight
if ( scrollDistance <= sign) {
binding.value()
}
}
selectwrap.addEventListener( 'scroll', selectwrap.scrollFn)
},
unmounted(el: Element){
const selectwrap = el.querySelector('.el-scrollbar_wrap')
if (selectwrap == null) return
selectwrap. removeEventListener( 'scroll' , selectwrap.scrollFn)
selectwrap.scrollFn = null
}
})
绑定自定义指令后:在组件中使用: v-vTablescroll=“需要执行的分页逻辑函数” 此处用
loadMore
为例:(类型我已经忽略)
/**
* 下拉动态加载逻辑
*/
/*下拉分页后的数据*/
const finalTableData = ref()
/*数据中转变量*/
const transferTableData = ref()
/* props.layerListData 是从外部传给table组件使用的原始数据,用transferTableData 中转一下 */
transferTableData.value = props.layerListData
let tempTableLayerData = []
let pageNum = 0
function loadMore(){
const layerList = transferTableData.value
// 数据总量
const total = layerList.length
// 每页条数
const pageSize = 10
// 如果加载结束就返回
if (pageNum * pagesize > total) return
// 计算每页的数据
const OnePageData = layerList.slice(pageNum * pagesize, (pageNum + 1)* pagesize)
// 每下拉一页之后merge到前面的数据中
const mergeData = tempTableLayerData.concat(OnePageData)
tempTableLayerData = mergeData
//形成最后的数据给table组件使用
finalTableData.value = tempTableLayerData
pageNum++
}
到这里主要的逻辑就差不多了,但是还有一些小拓展供大家参考:
重置数据
刷新当前数据或者切换成搜索当前数据的时候会需要
/**
* 重置数据逻辑
*/
/**
*重置数据*/
function resetLayerData() {
tempTableLayerData = []
finalTableData.value= []
transferTableData.value = []
pageNum = 0
//重置完数据之后,执行loadmore()数据会回到第一页的状态
transferTableData.value = props.layerListData
loadMore()
//这个时候表格需要滚动回第一行
}
/**
*聚焦到列表第一行*/
function focusFirstRow (){
// singleTableRef 是table的ref 对象
if (singleTableRef.value) {
nextTick(()=>{
// 滚第一行
singleTableRef.value.setScrollTop(o)}
// 让第一行是选中的样式,可以看一下文档组件中的用法
singleTableRef.value!.setCurrentRow(finalTableData.value[0])}
}
往往数据多的场景都会需要
搜索功能
(只是前端实现)效果如下:
搜索的逻辑如下
**
* 按图层名字搜索图层数据
*/
function handleFilterData (){
/*重置数据之后进行搜索*/
tempTableLayerData = []
finalTableData.value = [ ]
transferTableData.value = []
pageNum = 0
/*搜索数据*/
const searchRes = props.layerListData.filter(data =>{
return (
! searchVal.value ||
data.attrs.name.toLowerCase().includes( searchVal.value.toLowerCase())
)
})
/*搜索结果按照名称的长短排序*/
if ( searchVal.value) {
// 有值就进行排序
transferTableData.value = searchRes.sort(
(a, b) =>a.attrs.name.length - b.attrs.name.length)
}else {
// 无值就返回原来的数据
transferTableData.value = searchRes
}
nextTick(() =>{
// 搜索完回滚到顶部
singleTableRef.value.setScrollTop(O)
})
//在执行第一个分页的加载
loadMore()
到这里基本就结束了,还有其他的一些细节就不再展示了,vue2逻辑也大差不差,如果有什么不懂的地方请留言,我会进行解答~ 对您有用的话记得三连哦~3q