Element Plus 下拉框懒加载

需求背景

常见的需求中经常有下拉框作为搜索的条件之一,我们需要先调接口拉取数据供用户进行选择。当遇到数据量大,或考虑到随着时间推移,数据量会变得庞大的情况,通常接口会采取分页设计。

最佳实践

  1. 默认先只拉取第一页数据,供用户选择
  2. 当用户滚动至数据末尾,拉取下一页数据(数据懒加载)
  3. 支持关键词搜索
  4. 支持一键清空

实现细节

Vue项目我们团队基本上统一使用Element UI / Element Plus,本次针对 Element Plus的Select组件实现了公共方法 – 自定义指令完成懒加载。(Vue 3适用)

使用

// 引入
import vLoadMore from "@/utils/loadMore"

// 绑定指令
<el-select v-load-more="loadMoreData"></el-select>

原理

基于Element Plus Select组件滚动区域,监听滚动是否到达底部

懒加载逻辑

当元素内容的总高度 – 已滚动的高度 <= 元素的可见区域高度,代表当前滚动位置已经接近或到达底部,此时调用父组件传入回调方法即可。

初始状态

滚动到底部

Element Plus Select组件滚动区域选择

当页面中只用到一个下拉框,你可以直接使用类名定位。

当页面中有多个下拉框,上面的方法会导致数据错乱。查看Select DOM可以发现,不同的下拉框记录了不同的control id

而control id可以定位到对应的下拉框。举例:平台选择器的control id是”el-id-6389-3″,对应的下拉框DOM id也是”el-id-6389-3″

因此,我们可以利用以上属性定位到Select组件的实际滚动区域。

代码

/* Element Plus
   Select组件 自定义指令-触底加载更多
   使用:
       1. 页面中引入
       ```
        import vLoadMore from "@/utils/loadMore"
       ```
       2. 绑定自定义指令
       ```
       <el-select v-load-more="loadMoreData"></el-select>
       ```
 */
const vLoadMore = {
    mounted(el, binding) {
        const child = el.querySelector('.el-select__input')
        const id = child.getAttribute('aria-controls')
        const popper = document.getElementById(id)
        const SELECT_DOM = popper.parentElement

        SELECT_DOM.addEventListener('scroll', function () {
            const CONDITION = this.scrollHeight - this.scrollTop <= this.clientHeight
            if (CONDITION) {
                binding.value()
            }
        })
    }
}

export default vLoadMore

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注