赞
踩
在公司管理后台需要有一个 根据选择客户筛选拥有的服务 的功能
但是有上千条用户数据,一次性查询加载会导致页面有很长时间(大概4~5s)的空白期,用户体验很不友好。
故需要进行优化,针对这个问题,网上解决方案也挺多的,此处参考 https://juejin.cn/post/6844903710972182536 解决方案,根据项目做了部分减配
一方面优化MySQL查询语句,另一方面前端分页查询数据。
本文主要讲述如何修改 ElementUI 的el-select 组件支持分页查询数据
# directives/index.js import Vue from 'vue' export default () => { Vue.directive('el-select-scroll', { bind(el, binding) { // 获取滚动页面DOM let SCROLL_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap') let scrollPosition = 0 SCROLL_DOM.addEventListener('scroll', function () { // 当前的滚动位置 减去 上一次的滚动位置 // 如果为true则代表向上滚动,false代表向下滚动 let flagToDirection = this.scrollTop - scrollPosition > 0 // console.log(flagToDirection ? '滚动方向:下' : '滚动方向:上') // 记录当前的滚动位置 scrollPosition = this.scrollTop // 记录滚动位置距离底部的位置,在滚动位置距离滚动页面底部一定高度时在触发,例如距页面底部只有100px时触发handleScroll事件 const LIMIT_BOTTOM = 10 let scrollBottom = this.scrollHeight - (this.scrollTop + this.clientHeight) < LIMIT_BOTTOM // 如果已达到指定位置则触发 // 如果向下滚动 并且距离底部只有10px if (flagToDirection && scrollBottom) { // 将滚动行为告诉组件 binding.value(flagToDirection) } // 如果是向上滚动 并且距离顶部只有100px if (!flagToDirection && this.scrollTop < LIMIT_BOTTOM) { binding.value(flagToDirection) } }) } }) }
# app.js
import directive from "./directives";
Vue.use(directive)
<template> <el-select v-model="searchForm.user_id" v-el-select-scroll="handleScroll" size="mini" :loading="loadStatus" :placeholder="placeholder" value-key="id" @focus="handleFocus"> # 搜索框 <el-input type="text" size="mini" v-model="queryKeyword" @keydown.enter.native="remoteSearch" placeholder="回车搜索客户,按字母排序"></el-input> # 下拉列表数据 <el-option v-for="(el,key) in ownUserList" :key="key" :label="formatLabel(el)" :value="el.id"></el-option> </el-select> </template> <script> export default { name: "app-selectOwnUser", data() { return { searchForm: { user_id: "" }, ownUserList: [], loadStatus: false, pageNum: 1, queryKeyword: "", }; }, methods: { ajaxGetInfo(pageNum = this.pageNum){ this.loadStatus = true let params = { page: pageNum } get("api/user/lists", params).then(res => { this.loadStatus = false if (res.errcode) { this.$message({ showClose: true, message: res.msg, type: "error" }); return false; } this.ownUserList = this.ownUserList.concat(res.data); }); }, handleFocus(){ /** * select 获取焦点时,重置参数 * */ this.queryKeyword = ""; this.ownUserList = []; this.ajaxGetInfo(1); }, handleScroll(param){ /* * 处理滚动行为 * param: 滚动行为 * true 向下滚动 * false 向上滚动 */ // console.log(param) // 此处判断 !this.queryKeyword 是防止在搜索关键词的结果上追加数据 // 在后台判断关键词长度,至少要输入2个关键字,才可搜索 // 否则,还是会出现查询时间长的情况 if(param && !this.queryKeyword){ // 请求下一页数据 this.ajaxGetInfo(++this.pageNum) } }, remoteSearch(){ let params={ keyword: this.queryKeyword } this.loadStatus = true get("api/user/lists", params).then(res => { this.loadStatus = false if (res.errcode) { this.$message({ showClose: true, message: res.msg, type: "error" }); return false; } this.ownUserList = res.data; }); }, } } </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。