问题

项目中使用的是vue-element-template
当右侧content内容比较多时,或者表格单页数据量展示较多时,左边侧边栏菜单收缩展开的功能就会很卡顿,体验十分差,看了issue有人提出bug,但是也没有人给出一个比较好的解决方案。
在这里插入图片描述

分析问题

本人遇到的是表格单页展示过多引起的菜单收缩卡顿,分析了一下原因是,js执行阻塞了css动画,el-table开启了自动撑开宽度,需要时间重新计算渲染(设置了min-width的或开启fit)
在这里插入图片描述

解决方案:

  1. 使用虚拟滚动方案,目前el-table是没有该功能的,可以使用第三方改造的table
  2. 去除收缩动画,不过有点生硬。。注释掉src/style/sidebar.scss文件下的 transition: margin-left .28s;transition: width 0.28s; 俩行代码。
  3. 数据延迟重新渲染,等动画完成后重新渲染
    我发现src/style/sidebar.scss样式.main-container下的transition: margin-left .28s较卡,把它注释掉。接下来就是对tableData进行切割延迟重新渲染(只针对右侧是表格的情况下的解决方案,其他情况也可以用类似的方法)
    我写了一个mixin,方便多个组件可以共用
import { mapGetters } from 'vuex'

/* 优化菜单收缩卡顿 */
export const tableLoad = {
  data(){
    return {
      timeout:null
    }
  },
  computed:{
      ...mapGetters(['opened'])//展开收起的状态
  },
  watch:{
    opened() {
      let len = this.catchData.length//catchData是tableData深拷贝出来的
      if(len<=10)return
      this.tableData.splice(10, len)//当切换收缩状态时,表格只展示10条
      if(this.timeout) clearTimeout(this.timeout)
        this.timeout = setTimeout(() => {//分几步展示剩余的数据
          if(len>50){//超过50条
            let data= this.tableData.concat(this.catchData.slice(10, 40))
            this.setData(data)
            this.timeout = setTimeout(()=>{
              let data= this.tableData.concat(this.catchData.slice(40, 60))
              this.setData(data)
              if(len>60){//超过60条
                this.timeout = setTimeout(()=>{
                  let data= this.tableData.concat(this.catchData.slice(60, len))
                  this.setData(data)
                  clearTimeout(this.timeout)
                },500)
              }
            },1300)
            return
          }
          let data= this.tableData.concat(this.catchData.slice(10, len))
          this.setData(data)
      }, 500)
    }
  },
  methods:{
    setData(data){
      this.$set(this,'tableData',data )
    },
  },
  beforeDestroy(){
    clearTimeout(this.timeout)
  }
}

在所需页面导入示例

import { tableLoad } from '@/utils/mixin'
export default{
	 mixins:[tableLoad],
	 data(){
		return{
			tableData:[]
			catchData:[]
		}
	},
	methods:{
		getData(){
			//...
			this.tableData = arr
			this.catchData = deepClone(arr);//自行写深拷贝方法
		}
	}
}

至此,问题解决,本人用的是方法3,虽然方法low,但是起码能用哈哈哈…

各位大佬,如有更好的解决方案,请踢我一脚

GitHub 加速计划 / vu / vue-element-admin
87.26 K
30.42 K
下载
PanJiaChen/vue-element-admin: 是一个基于 Vue.js 和 Element UI 的后台管理系统模板,支持多种数据源和插件扩展。该项目提供了一个完整的后台管理系统模板,可以方便地实现后台管理系统的快速搭建和定制,同时支持多种数据源和插件扩展。
最近提交(Master分支:26 天前 )
0caa975e - 2 年前
cd3f7267 - 2 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐