在我们实际开发中,常常需要优化以下页面,加快页面的响应速度,下面来介绍一下,前端在使用 Element-ui 下拉框时使用懒加载来解决页面卡顿或者响应慢的问题;
场景描述:
场景描述一:当后端给前端返回的数据有很多成千上万个数据时,我们如果直接接收并使用的话会造成页面响应很慢或者卡顿;
场景描述二:初始页面展示的是下拉框未加载的数据,初始页面跳转到编辑页面时的不回显的问题;
解决思路:
懒加载解决思路:监听滚动条事件,当滚动条到底时,增加显示数据个数;
回显解决思路:先把我们选中的数据加在列表最前面,当加载到了我们选中的数据后删除最前面我们自己加进去的数据。
解决方案:
<template>
<el-table v-loading="loading" :data="tableData" style="width: 100%; min-height: 100%" ref='infoTable'>
<el-table-column type="index" label="序号"></el-table-column>
<el-table-column prop="value" label="姓名"></el-table-column>
<el-table-column label="编辑">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog title="编辑" :visible.sync="isVisible" width="98%">
<el-select
v-model="items"
size="small"
v-el-loadmore:number="loadMore(number)"
filterable
remote
:remote-method="remoteValue(query)"
>
<el-option
v-for="(item, index) in list.slice(0, number)"
:key="index"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-dialog>
</template>
<script>
import Vue from "vue";
// 自定义一个vue指令监听滚动条
Vue.directive(
'el-loadmore', {
bind(el, binding) {
// 获取element-ui定义好的scroll盒子
const SELECT_DOM = el.querySelector('.el-select-dropdown .el-scrollbar .el-select-dropdown__wrap');
// 打印一下看看有没有获取到 element-ui 定义的scroll盒子
console.log('SELECT_DOM', SELECT_DOM)
SELECT_DOM.addEventListener('scroll', function () {
/**
* scrollHeight 获取元素内容高度(只读)
* scrollTop 获取设置元素的偏移值,常用于计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条时, scrollTop的值默认为0.
* clientHeight 读取元素的可见高度(只读)
* 如果元素滚动到底, 下面等式返回true, 没有则返回false:
* ele.scrollHeight - ele.scrollTop === ele.clientHeight;
*/
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
// 判断 condition 的值是否为true,为true 时调用 loadMore方法
if (condition) binding.value();
});
}
}
)
export default {
data() {
return {
tableData: [], // 初始页面的表格数据
list: [], // 下拉框option绑定的数据
items: {}, // 下拉框model绑定的数据
curRow: {}, // 当前正在编辑的行数据
number: 10,
timer: null,
isVisible: false, // 编辑页面的显示隐藏
}
},
mounted(){
this.getList()
},
methods: {
// 获取初始列表
getList(){
$.ajax({
url: "/getlist", // 测试路径
type: "get",
contentType: 'application/json;charset=utf-8',
success (res) {
if (res.state == "success") {
console.log(res.data) // res.data [{id: "01001", value: `张一`}, {id: "01002", value: `张二`}, .....]
// 如果是编辑页面时,如果把之前push的数据删除
if(this.curRow){
res.data.forEach( item => {
if(item.id== this.curRow.id){
this.list.splice(0,1)
}
})
}
this.list= [...this.list, ...res.data];
}
},
error: function (text) {
}
});
},
// 懒加载增加数据个数
loadMore(n){
return () => this.number += 5 //每次滚动到底部可以新增条数 可自定义
},
// 远程搜索功能
remoteValue(val) {
if (val != '') {
this.listerValue(val)
} else {
this.getList();
}
},
// 模糊查询
listerValue (val) {
this.loading = true;
var list= JSON.parse(JSON.stringify(this.list));
if (this.timer) {
window.clearTimeout(this.timer)
this.timer = null;
}
this.timer = window.setTimeout( () => {
this.loading = false;
this.list= list.filter( item => {
if(item.value.includes(val)){
return item
}
})
}, 200)
},
// 编辑页面
handleClick: function (row) {
this.setValue (row);
this.isVisible = true;
},
// 设置编辑页面的初始值
setValue (row) {
this.curRow = row
this.list= []
//将当前行信息 push 到列表数组最前面,解决当前编辑的行数据的下拉框是没有加载的数据时回显
this.list.push({
id: this.curRow.id,
value: this.curRow.value
})
this.getList();
}
}
}
</script>
如有不足,望大家多多指点! 谢谢!