摘要:
针对数据量大的选择器,需要分页从后端接口,前端监听选择器下拉框的滚动事件,当往下滚动至底部一定位置时需要调用接口,可以通过指定以指令实现该功能。
指令的实现
import Vue from 'vue'
const elLoadMore = {
inserted(element, binding, vnode) {
const SELECTWRAP_DOM = element.querySelector(
'.el-select-dropdown .el-select-dropdown__wrap'
)
let scrollPosition = 0
SELECTWRAP_DOM.addEventListener('scroll', function () {
// 当前的滚动位置 减去 上一次的滚动位置
// 如果为true则代表向上滚动,false代表向下滚动,判断不加的话会频繁触发滚动事件,引起bug
const flag = this.scrollTop - scrollPosition > 0
scrollPosition = this.scrollTop
const LIMIT_HEIGHT = 10
const CONDITION = this.scrollHeight - (this.scrollTop + this.clientHeight) < LIMIT_HEIGHT
if (flag && CONDITION) {
// 将滚动行为告诉组件
binding.value && binding.value()
}
})
}
}
const install = function(Vue) {
Vue.directive('checkInt', elLoadMore)
}
if (Vue) {
window.checkInt = elLoadMore
Vue.use(install) // eslint-disable-line
}
export default elLoadMore
具体使用
- html中使用
<el-select
v-model="searchData.carrierIdList"
placeholder="请选择承运商"
filterable
remote
clearable
multiple
collapse-tags
:remote-method="(query) => getOptionsDataList(query, true)"
v-elLoadMore="getOptionsDataList"
@visible-change="visibleChangeOptions"
>
el-option v-for="item in optionsData" :value="item.value" :key="item.value" :label="item.label" />
</el-select>
- 请求数据处理
export default {
data() {
return {
optionsData: [],
optionsDataMore: false,
optionsDataParams: {
page: 0,
size: 50,
lastKeyword: undefined,
},
}
},
methods: {
// 承运商下拉数据
getOptionsDataList: debounce(async function (keyword, isReset) {
keyword = keyword || undefined // 减少不必要的重复请求
const isResetData = keyword !== this.optionsDataParams.lastKeyword || isReset
if (isResetData) {
this.optionsData = []
this.optionsDataParams.page = 0
this.optionsDataMore = false
}
this.optionsDataParams.lastKeyword = keyword
// 没有更多
if (this.optionsDataMore) { return }
const res = await crmSupOptions({
page: ++this.optionsDataParams.page,
size: this.optionsDataParams.size,
keyword: keyword,
})
const { records, total } = res.data || {}
if (res?.code === '200') {
const list = (records || []).map((item) => ({
...item,
value: item.supplierId,
label: item.supplierName,
}))
this.optionsData.push(...list)
this.optionsMore = this.optionsDataParams.page * this.optionsDataParams.size >= total
} else {
this.$Message.error(res.msg || '请求失败')
}
}, 300),
// 下拉框弹出重新加载数据
visibleChangeOptions(val) {
if (val) {
this.getOptionsDataList('', true)
} else {
this.optionsData = []
}
}
}
}