Escena del proyecto:
Es necesario que haya una función en la administración de la empresa entre bastidores para filtrar los servicios que pertenecen a clientes seleccionados
Descripción del problema:
Pero hay miles de datos de usuario, la carga de consultas por única vez provocará un período en blanco prolongado (alrededor de 4 ~ 5 s) en la página, y la experiencia del usuario es muy poco amigable.
Por lo tanto, necesita ser optimizado. Para este problema, hay muchas soluciones en línea. Consulte https://juejin.cn/post/6844903710972182536 para obtener la solución, y se han realizado algunas reducciones de acuerdo con el proyecto.
solución:
Por un lado, se optimiza la declaración de consulta de MySQL y, por otro lado, los datos de consulta de paginación de front-end.
Este artículo describe principalmente cómo modificar el componente el-select de ElementUI para admitir datos de consulta de paginación
Definir instrucciones
# 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)
}
})
}
})
}
Introduce instrucciones en vue
# app.js
import directive from "./directives";
Vue.use(directive)
el-seleccionar agregar nuevo comando el-seleccionar-desplazarse
<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>