当前位置: 首页 > news >正文

Vue3 + ts+ elementUi 实现后台数据渲染到下拉框选项中,滑动加载更多数据效果

前言

功能需求:下拉框中分页加载后端接口返回的人员数据,实现滑动加载更多数据效果,并且可以手动搜索定位数据,此项目使用Vue3 + ts+ elementUi 实现

实现

把此分页滑动加载数据功能封装成vue中的hooks,文件命名为useMoreUser.ts

import {ref,reactive,nextTick} from 'vue'export  const useMoreUser = () => {const selectMoreData = reactive({page: 0, //当前页loading: false, //loadinghasMore: true, //判断是否还有更多数据selectValue: '', //下拉框选中数据selectOptions: [] //下拉框选项})// 人员列表加载数据列表【newPage: 页数,name: 搜索条件】const loadDataList = async (newPage: number, name?: string = '' ) => {try {selectMoreData.loading = true;//后端接口,入参为搜索条件人员姓名,页数let res = await getUserList(name, newPage); if (newPage === 1) { //初始化selectMoreData.selectOptions = [];}//存储后端接口返回数据selectMoreData.selectOptions.push(...res.rows);//判断是否还有更多数据selectMoreData.hasMore = selectMoreData.selectOptions.length < res.total;selectMoreData.page = newPage;} catch (err) {console.error(err);} finally {selectMoreData.loading = false;}};//加载更多数据const handleLoadMore = async (newPage: number,  name?: string = '' ) => {await loadDataList(newPage,name);};//返回下拉框选项const getList = ()=>{return selectMoreData.selectOptions;}//导出数据方法等return {selectMoreData,getList, loadDataList, handleLoadMore}
}

再继续封装下拉框选项组件 option.vue

<!-- 监听 el-select 的滚动,并提供触底加载数据的回调 -->
<template><el-option ref="el" class="el-select-loading" value=""><template v-if="hasMore"><el-icon class="el-select-loading__icon"><Loading /></el-icon><span class="el-select-loading__tips">{{ loadingText || "正在加载" }}</span></template><template v-else>{{ noMoreText || "到底了~" }}</template></el-option>
</template><script setup lang="ts">import { onMounted, onUnmounted, ref } from "vue";import { ElOption } from "element-plus";interface Props {// 当前页码page: number;// 是否加载中,用来过滤重复的加载loading: boolean;// 加载中的提示文案loadingText?: string;// 是否有更多数据可加载hasMore: boolean;// 没有更多数据的提示文案noMoreText?: string;}const props = defineProps<Props>();interface Emits {(event: "loadMore", data: number): any;}const emit = defineEmits<Emits>();const el = ref<typeof ElOption>();const observer = ref<IntersectionObserver>();// 组件加载成功,监听滚动onMounted(() => {if (!el.value) {return;}const callback: IntersectionObserverCallback = (entries) => {if (props.loading || !props.hasMore || !entries[0].isIntersecting) {return;}emit("loadMore", props.page + 1);};const options: IntersectionObserverInit = {root: el.value.$el.parentElement?.parentElement,rootMargin: "0px 0px 0px 0px",};observer.value = new IntersectionObserver(callback, options);observer.value.observe(el.value.$el);});// 组件卸载成功,取消滚动监听onUnmounted(() => {if (!el.value) {return;}observer.value?.unobserve(el.value.$el);});
</script><style lang="scss" scoped>.el-select-loading {display: flex;align-items: center;justify-content: center;cursor: initial;pointer-events: none;color: var(--el-color-info);font-size: 12px;&__icon {font-size: 16px;animation: rotate 1.5s linear infinite;}&__tips {margin-left: 6px;}@keyframes rotate {from {transform: rotate(0deg);}to {transform: rotate(360deg);}}}
</style>

最后到咱们真正使用页面index.vue,封装时候有些费事,但是使用起来就简单了
template部分

 <el-select class="customSelect" filterable remote :remote-method="remoteMethod"v-model="user" placeholder="请选择人员"style="width: 100%"><el-optionv-for="item in selectMoreData.selectOptions":key="item.userId":label="`${item.userName}`":value="item.userId"><span style="float: left">{{ `${item.userName}` }</span></el-option><ElSelectLoading:page="selectMoreData.page":loading="selectMoreData.loading":hasMore="selectMoreData.hasMore"@loadMore="handleLoadMore"/></el-select>

script部分

<script lang="ts" setup>
import {ref, reactive, onUnmounted, onMounted, nextTick, computed, watch} from 'vue'
import ElSelectLoading from "@/components/Option/option.vue";
import {useMoreUser} from '@/hooks/useMoreUser.ts'
const {selectMoreData, loadDataList, handleLoadMore} = useMoreUser();const user = ref('');
const remoteMethod = (query: string) => {loadDataList(1, query);
}
</script>
http://www.lryc.cn/news/230070.html

相关文章:

  • Elasticsearch 索引库操作与 Rest API 使用详解
  • 线性代数(四)| 解方程 齐次性 非齐次性 扩充问题
  • 快乐数问题
  • 8 历史服务器配置
  • 读书笔记:《精益数据分析》
  • 酷柚易汛ERP- 组装单与拆卸单操作
  • yolov8训练
  • 抖音短视频账号矩阵系统、短视频矩阵源码+无人直播源码开发可打包
  • NI和EttusResearchUSRP设备之间的区别
  • WPF UI样式介绍
  • 【开源】基于Vue.js的校园失物招领管理系统的设计和实现
  • 计算机视觉中目标检测的数据预处理
  • es 查询多个索引的文档
  • 用java把服务器某个目录日志实时打印出来
  • 金融信贷行业如何准确——大数据精准定位获客渠道
  • LeetCode 面试题 16.21. 交换和
  • 未来之路:大模型技术在自动驾驶的应用与影响
  • Skywalking流程分析_5(字节码增强)
  • Windows conan环境搭建
  • 如何使用Cpolar+Tipask,在ubuntu系统上搭建一个私人问答网站
  • 怎么在uni-app中使用Vuex(第一篇)
  • 【MySQL】库的相关操作 + 库的备份和还原
  • 网络安全基础之php开发文件上传的实现
  • [文件读取]cuberite 文件读取 (CVE-2019-15516)
  • SpringBoot 自定义参数校验(5)
  • Win Docker Desktop + WSL2 部署PyTorch-CUDA服务至k8s算力集群
  • JLMR Micro Super Resolution Algorithm国产微超分算法DEMO
  • Docker的安装配置与使用
  • macOS文本编辑器 BBEdit 最新 for mac
  • Android Audio实战——音量设置Hal(二十)