Element-ui 之 解决后端返回大量数据时页面卡顿或者反应慢的问题(懒加载以及下拉框回显未加载数据)


 在我们实际开发中,常常需要优化以下页面,加快页面的响应速度,下面来介绍一下,前端在使用 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>




如有不足,望大家多多指点! 谢谢!

你可能感兴趣的:(Element-ui,vue.js,前端)