赞
踩
需求:下拉框一开始请求第一页的内容,滚动到最后的时候,请求第二页的内容,如此反复,直到所有数据加载完成。
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获取不到
- <el-select
- v-el-select-loadmore="{
- selector: '.myOption .el-select-dropdown .el-select-dropdown__wrap',
- loadFunction: loadMore
- }"
- v-model="userForm.accountName"
- placeholder="请选择用户"
- popper-class="myOption"
- >
- <el-option
- v-for="(item, index) in userData"
- v-loading="optionLoading(index)"
- :key="item.id"
- :label="item.username"
- :value="item.id"
- />
- </el-select>
-
- //总共的数据条数
- 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代码如下:
- <template>
- <el-form-item label="用户名称:">
- <el-select
- popper-class="myOption"
- v-model="accountName"
- placeholder="请输入或选择用户"
- v-el-select-loadmore="loadMore">
- <el-option v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value" />
- </el-select>
- </el-form-item>
- </template>
-
- <script setup lang="ts">
- import {ref,onMounted} from 'vue'
- let page = ref(1)
- let pageSize = ref(10)
- let total = 100
- let totalCount=6
- let stopLoading = false
- let accountName = ref('')
- const options = ref([])
- onMounted(() => {
- options.value.length=0
- loadOptions(1)
- })
-
- function loadMore() {
- //这里设置接口的最大页数totalCount为6,超过6页就没数据了
- if (page.value <= totalCount) {
- page.value += 1;
- //获得接口数据
- loadOptions(page.value);
- }
- }
-
- function loadOptions(page:number) {
- // 模拟接口发送数据,异步加载数据
- setTimeout(() => {
- for (let i = (page-1)*10+1; i <= page*10; i++) {
- options.value.push({
- value: `Option${i}`,
- label: `Option${i}`
- });
- }
- }, 500);
- }
- //在自定义指令
- const vElSelectLoadmore = {
- mounted(el: any, binding: any) {
- // 坑:
- const SELECTWRAP_DOM:Element|null = document.querySelector(
- '.myOption .el-select-dropdown .el-select-dropdown__wrap'
- );
- if (SELECTWRAP_DOM) {
- SELECTWRAP_DOM.addEventListener('scroll', function () {
- const condition = this.scrollTop+this.clientHeight >= this.scrollHeight-1;
- // 当滚动条滚动到最底下的时候执行接口加载下一页
-
- if (condition) {
- binding.value && binding.value()
- }
- });
- }
-
- },
-
- }
-
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。