el-autocomplete 实现滚动加载
vue2 写的不是很多了, 看了一下 element 中的 el-autocomplete 并没有滚动加载的API, 而且试了一下, el-autocomplete 并不能够使用 element 的 InfiniteScroll 无限滚动, 所以我们可以自定义一个指令, 来动态获取滚动条的参数,来触发对应的回调,实现无限滚动的效果, 下面来看一下实现:
- 模板中的代码
注意点: 模板中的 api 很多时候要根据自己的需求来定义, 需要自己去查看一下element组件库中 组件对应的api,比如下面的 :trigger-on-focu 这个是因为我项目中需求 input 聚焦的时候就要显示下面的select框, value-key 是使用我传的数组中 对象的 指定这个key 的value作为显示的文本, 这个默认值是value,其他的还请自行查看熟悉
我这个项目中没有使用 select 事件, 因为我的弹窗有一个 确认按钮, 确认的之后直接获取 双向绑定的 searchICCIDValue 即可
<el-autocomplete
class="inline-input"
ref="autocomplete"
v-scrollLoad="load"
value-key="iccid_number"
v-loading="iccicLoading"
v-model="searchICCIDValue"
:fetch-suggestions="querySearch"
placeholder="请选择或搜索ICCID号"
:trigger-on-focus="true"
></el-autocomplete>
- js代码 只展示 配置项
注意点: 滚动到底以后,我们需要使用 this.data.suggestions 来获取和修改 select 中显示的数据,autocomplete 组件显示的数据不是配置项,我们无法配置,他只是通过 querySearch 这个回调函数中的第二个参数, 是函数, 这个函数会传入我们的数组, 每次我们初始更改的和修改的 要依赖于这个回调函数, 滚动到底部以后,第二次想在这个基础上进行修改,就需要动态获取。 load 函数需要前置条件来判断是否进行请求, 我这里使用的是分页的信息来进行判断。
directives: {
// 滚动事件 自定义指令
scrollLoad: {
bind(el, binding, vnode) {
const wrapDom = el.querySelector(
'.el-autocomplete-suggestion__wrap'
)
wrapDom.addEventListener(
'scroll',
(e) => {
const condition =
wrapDom.clientHeight +
wrapDom.scrollTop -
wrapDom.scrollHeight
if (condition > 0 && !vnode.context.loading) {
//滚动到底部则执行滚动方法load,binding.value就是v-scrollLoad绑定的值,加()表示执行绑定的方法
binding.value()
}
},
false
)
},
},
},
methods:{
querySearch(queryString, cb) {
// 查询 用的是学生证的校id
const { org_id } = this.stuCardInfo
getICCIDInfoApi({
org_id,
cur_page: 1,
page_size: this.pageSize,
search: queryString,
}).then((res) => {
const { list, total_page } = res
this.totalPage = total_page
this.restaurants = list
console.log('querySearch', queryString)
cb(this.restaurants)
})
},
// 滚动到底 加载更多
load() {
console.log(this.curPage, this.totalPage)
if (this.curPage === this.totalPage) return
const { org_id } = this.stuCardInfo
this.iccicLoading = true
// 接口请求数据
getICCIDInfoApi({
org_id,
cur_page: this.curPage,
page_size: this.pageSize,
search: this.searchICCIDValue,
})
.then((res) => {
const { list, total_page, cur_page } = res
this.restaurants = this.restaurants.concat(list)
this.$refs['autocomplete'].$data.suggestions =
this.restaurants
this.totalPage = total_page
this.curPage = cur_page
})
.finally(() => (this.iccicLoading = false))
},
}