需求:下拉框一开始请求第一页的内容,滚动到最后的时候,请求第二页的内容,如此反复,直到所有数据加载完成。
selectLoadMore.ts
//自定义指令:实现下拉框下拉到末尾时,加载下一页的内容 // 使用时传两个参数,一个是下拉框的class,一个是下拉框滚动到末尾时触发的函数,比如: // v-el-select-loadmore="{ // selector: '.myOption .el-select-dropdown .el-select-dropdown__wrap', // loadFunction: loadMore // }" export default { mounted(el, binding) { //解构传来的值 const { value: { selector, loadFunction } } = binding const SELECTWRAP_DOM = document.querySelector(selector) if (SELECTWRAP_DOM) { // 监听事件的处理函数,把函数单独写出来,方便销毁 const scrollHandler = () => { const condition = SELECTWRAP_DOM.scrollTop + SELECTWRAP_DOM.clientHeight >= SELECTWRAP_DOM.scrollHeight - 1 if (condition) { loadFunction() } } //赋值,为了方便销毁,这里很重要,不然销毁的时候找不到dom和对应的回调函数!!! el.dom = SELECTWRAP_DOM el.event = scrollHandler //监听滚动事件 SELECTWRAP_DOM.addEventListener('scroll', scrollHandler) } }, //销毁,会在关闭弹窗时触发(这里的el-select写在弹窗里) beforeUnmount(el) { if (el.dom) { el.dom.removeEventListener('scroll', el.event) } } } 记得在main.ts里面注册成全局组件!!!!
main.ts
import vElSelectLoadmore from '@/utils/tools/selectLoadMore' app.directive('el-select-loadmore', vElSelectLoadmore) //全局自定义指令 app.mount('#app') 使用的vue文件
//使用时在指令里传值,这里有个坑! //在el-select给一个参数popper-class="myOption",因为element-plus中ei-select的选项是使用的popper.js生成的,无法直接获取,直接获取下拉框的dom获取不到 //总共的数据条数 let totalCount: number = 0 //当前滚动页 let page: number /** * 自定义指令触发的回调 */ function loadMore() { //计算总页数 let maxPagSize: number = Math.max(Math.ceil(totalCount / 10), 1) //不超过总页数才发请求 if (page < maxPagSize) { page += 1 //发请求,获得接口数据 getUserListWrap(page, 10) } } /** * 控制下拉框loding是否出现,isOptionLoading是在getUserListWrap请求函数里面的,userData是请求函数获得是下拉框数据,这样可以使下拉到最后一个option的时候,出现loding效果,更加完善美观 * @param index 下拉框循环的index */ function optionLoading(index: number): boolean { if (isOptionLoading.value && index == userData.length - 1) { return true } else { return false } } 总结:
1、 在el-select给一个参数popper-class="myOption",因为element-plus中el-select的选项是使用的popper.js生成的,无法直接获取,直接获取下拉框的dom获取不到
2、在自定义指令里面销毁事件的时候,在mounted必须把事件存在el上,不然不好销毁,一开始是以下这么写的:发现这样不好销毁,因为在 beforeUnmount拿不到function,this只能按以下这么写才行,如果单独把funtion拎出来,this就报错找不到
export default { mounted(el, binding) { const { value: { selector, loadFunction } } = binding const SELECTWRAP_DOM = document.querySelector(selector) if (SELECTWRAP_DOM) { SELECTWRAP_DOM.addEventListener('scroll', function () { const condition = this.scrollTop + this.clientHeight >= this.scrollHeight - 1 if (condition) { loadFunction() } }) } } } vue3的demo代码如下: