el-select分页懒加载

场景

修改个人信息时,职务信息回显,且加载全部职务数据的话,数据量太大,导致接口请求时间太久,用户体验不好。职务选项是el-select下拉选择,并且官方el-select不支持分页懒加载。

实现思路

1. 点击修改时,把职务id和职务名称带过来,直接添加到 list 中,保证回显速度。

2. 如果只有id没有名称,就用id查询列表,返回一条数据,实现回显,体验速度其次(跟后端协调好,接口要支持id检索和名称模糊检索)。

3. 同时加载第一页数据,取20条,保证下拉列表能有滚动效果。

4. 自定义vue滚动指令方法,获取下拉DOM,实现滚动触底加载,然后拼接数据,触底时判断现有数据量是否小于总数据量,然后决定是否加载下一页数据。

5. 支持搜索关键字检索,当输入关键字检索触发搜索时,page重置为1,同时支持触底分页;清空关键字时亦同理。

6. 当搜索关键字查询 list 为空,并且触发下拉框隐藏时,page重置为1,并重新加载第一页数据,避免重新触发下拉框显示时,没有内容的奇怪现象。

7. 当选择时,更新回显数据为选择的数据,并把list重置为选择数据数组,并加载第一页数据,重新赋值给list。

思路完成,上代码。

实现代码

页面处理代码

test.vue

<!-- 下拉部分 -->
<el-form-item label="选择xx:">
    <el-select
        v-model="formData.storeld"
        placeholder="请选择"
        filterable
        clearable
        remote
        reserve-keyword
        v-scroll="handleScroll
        @change="handleChange"
        :remote-method="remoteMethod"
        @visible-change="visibleChange"
        style="width: 100%;
    >
        <el-option
            v-for="item in storelist'
            :key="item.id"
            :label="item.name
            :value="item.id"
        >
        </el-option>
    </el-select>
</el-form-item>

<script lang='ts'>
// 数据部分
@Prop({ required: true }) public srcData!: any // 当前的数据对象

public isLoading = false // 加载状态
public showRow: any = {} // 需要回显的下拉数据对象
public storelist = [] // 下拉列表
public page = 1 // 页码
public pageSize = 20 // 每页分页数量
public total = 0 // 数据总量
public formData = {} // 提交表单数据

/**
 * 方法部分
 */
mounted() {
    const { storeId, storeName }  = this.srcData
    this.$set(this.formData, 'storeId', storeId)
    // storeId一定存在,sotreName不一定,所以做个判断
    if (storeId && storeName) {
        this.showRow = { id: storeId, name: storeName }
        this.storeList = [this.showRow]
        this.getStoreList({})
    } else {
        this.getStoreList({ storeId })
    }
}
// 处理滚动事件
handleScroll (event) {
    const { scrollTop, scrollHeight, clientHeight } = event.target
    const isNearBottom = scrollTop + clientHeight >= scrollHeight // 触底加载更多
    if (isNearBottom && !this.isLoading && this.storelist.length < this.total) {
        this.page += 1
        this.getStoreList({})
    }
}
// 处理选择事件
handleChange(v) {
    if (v) {
        const row = this.storeList.filter(item => v === item.id)
        this.showRow = row[0]
    }
    this.storeList = [this.showRow]
    this.page = 1
    this.getStoreList({})
}
// 处理搜索事件
remoteMethod(query: string) {
    this.page = 1
    if (query !== '') {
        this.getStoreList({ storeName: query })
    } else {
        this.getStoreList({})
    }
}
// 处理下拉显示隐藏事件
visibleChange(v: boolean) {
    if (v === false && this.storeList.length === 0) {
        this.getStoreList({})
    }
}
// 获取下拉列表
getStoreList (obj: { storeId?: string, storeName?: string }) {
    const { storeId, storeName } = obj
    const params = {
        page: this.page,
        pageSize: this.pageSize
    }
    if (storeId) {
        params.id = storeId
    }
    if (storeName) {
        params.name = storeName 
    }
    this.isLoading = true
    const url = '/getList'
    JavaHttp.postDataCallback(url, params, (ret: boolean, data: any) => {
        this.isLoading = false
        if (ret === true && data.code === 0) {
            const list = data.data.list || []
            this.total = data.data.total || 0
            if (storeId) {
                this.showRow = list[0]
                this.storeList = list
                this.getStoreList({})
            } else {
                if (this.page === 1) {
                    this.storeList = list
                } else {
                    this.storeList = this.storeList.concat(list)
                }
            }
        }
    })
}
</script>

自定义指令v-scroll

main.ts

Vue.directive('scroll', {
    inserted: function(el, binding) {
        const selectDropdown: any = el.querySelector(
            '.el-select-dropdown .el-select-dropdown__wrap'
        )
        selectDropdown.addEventListener('scroll', binding.value)
    }
})

注意:我们这里用 class 类名取的 el-select 下的下拉滚动区域DOM对象,如果组件升级或者类名修改,要注意替换。或者可以用其他方式获取下拉滚动区域DOM。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值