vue(element-ui)表格数据量多卡死

一、需求如下:

根据用户输入生成多行可供编辑的表格,如下图:


根据用户输入的检测数量来显示表格行数

二、初步想法

根据用户输入对其绑定的数组新增行

// 根据检测数量和回填信息生成测点信息表
    ProducpileList(val) {
      if (typeof val != 'number') return
      if (val == 0) {
        this.form.pileList = []
        return
      }
      this.form.pileList = []
      for (let i = 0; i < val; i++) {
        let itm = {}
        itm.index = i + 1
        if (this.IsForm1) {
          itm.value1 = value
          itm.value2 = value
          itm.value3 = value
          itm.value4 = value
          itm.value5 = value
          itm.value6 = value
        } 
        this.form.pileList.push(itm)
      }
    },

结果:因为使用的element-ui的表格加上嵌套的编辑框,数据量少能实现,数据量大一点就会卡顿甚至卡死

三、最终解决

引用了第三方库umy-ui(具体可参考:https://www.umyui.com/umycomponent/installation
1.使用npm install umy-ui安装
2.在main.js中引入(我这里全局引入的,也可按需引入,具体参考链接https://www.umyui.com/umycomponent/quickstart):

  import UmyUi from 'umy-ui'
  import 'umy-ui/lib/theme-chalk/index.css';// 引入样式
  Vue.use(UmyUi);

3.最后效果如下:

新增了一万行数据丝毫不卡顿

4.具体代码

<!-- 低应变 -->
<template>
    <ux-grid
             border
             :data="pileList"
             keep-source
             ref="plTable"
             show-summary
             :edit-config="{trigger: 'click', mode: 'cell'}"
             :row-height="rowHeight"
             :max-height="height">
      <ux-table-column fixed
                       align='center'
                       type="index"
                       title="序号"
                       min-width="50">
      </ux-table-column>
      <ux-table-column align='center'
                       title="桩号"
                       field="pileNo"
                       :edit-render="{autofocus: '.el-input__inner'}"
                       min-width="80">
        <template v-slot:edit="scope">
          <el-input v-model="scope.row.pileNo"></el-input>
        </template>
      </ux-table-column>
      <ux-table-column field="pileLength"
                       align='center'
                       title="桩长(m)"
                       :edit-render="{autofocus: '.el-input__inner'}"
                       min-width="100">
        <template v-slot:edit="scope">
          <el-input-number style="width:100%"
                           v-model="scope.row.pileLength"
                           @change="scope.row.index==1?valuechange(scope.row.pileLength,'pileLength'):null"
                           :controls='false'
                           :min="0"></el-input-number>
        </template>
      </ux-table-column>
      <ux-table-column field="pileDiameter"
                       title="桩径(mm)"
                       align='center'
                       :edit-render="{autofocus: '.el-input__inner'}"
                       min-width="100">
        <template v-slot:edit="scope">
          <el-input-number style="width:100%"
                           v-model="scope.row.pileDiameter"
                           @change="scope.row.index==1?valuechange(scope.row.pileDiameter,'pileDiameter'):null"
                           :controls='false'
                           :min="0"></el-input-number>
        </template>
      </ux-table-column>
      <ux-table-column field="pileDate"
                       align='center'
                       title="成桩日期"
                       :edit-render="{autofocus: '.el-input__inner'}"
                       min-width="130">
        <template v-slot:edit="scope">
          <el-date-picker v-model="scope.row.pileDate"
                          @change="scope.row.index==1?valuechange(scope.row.pileDate,'pileDate'):null"
                          size="small"
                          align="center"
                          type="date"
                          placeholder="选择日期"
                          format="yyyy年MM月dd日"
                          value-format="yyyy-MM-dd"
                          :picker-options="pickerOptions">
          </el-date-picker>
        </template>

      </ux-table-column>
      <ux-table-column field="powerLevel"
                       align='center'
                       :edit-render="{autofocus: '.el-input__inner'}"
                       title="设计强度等级"
                       min-width="120">
        <template v-slot:edit="scope">
          <el-select v-model="scope.row.powerLevel"
                     style="width:100%"
                     @change="scope.row.index==1?valuechange(scope.row.powerLevel,'powerLevel'):null"
                     filterable
                     clearable
                     no-match-text="无匹配数据"
                     placeholder="请选择">
            <el-option v-for="item in powerLevelList"
                       :key="item.value"
                       :title="item.title"
                       :value="item.title">
            </el-option>
          </el-select>
        </template>
      </ux-table-column>
      <ux-table-column field="pileBearing"
                       align='center'
                       title="承载力特征值(KN)"
                       :edit-render="{autofocus: '.el-input__inner'}"
                       min-width="150">
        <template v-slot:edit="scope">
          <el-input-number style="width:100%"
                           v-model="scope.row.pileBearing"
                           @change="scope.row.index==1?valuechange(scope.row.pileBearing,'pileBearing'):null"
                           :controls='false'
                           :min="0"
                           :max="999"></el-input-number>
        </template>
      </ux-table-column>
      <ux-table-column field="forceLayer"
                       align='center'
                       :edit-render="{autofocus: '.el-input__inner'}"
                       title="桩端持力层"
                       min-width="110">
        <template v-slot:edit="scope">
          <el-input v-model="scope.row.forceLayer"
                    @change="scope.row.index==1?valuechange(scope.row.forceLayer,'forceLayer'):null"></el-input>
        </template>
      </ux-table-column>
    </ux-grid>
</template>

<script>
export default {
  name: 'DyAddTable',
  data() {
    return {
      rowHeight: 55,
      pickerOptions: {
        shortcuts: [
          {
            text: '今天',
            onClick(picker) {
              picker.$emit('pick', new Date())
            },
          },
          {
            text: '昨天',
            onClick(picker) {
              const date = new Date()
              date.setTime(date.getTime() - 3600 * 1000 * 24)
              picker.$emit('pick', date)
            },
          },
          {
            text: '一周前',
            onClick(picker) {
              const date = new Date()
              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
              picker.$emit('pick', date)
            },
          },
        ],
      },
    }
  },
  methods: {
    valuechange(val, name) {
      this.pileList.forEach((item) => {
        this.$set(item, name, val)
      })
    },
  },
  mounted() {
    this.$refs.plTable.reloadData(this.pileList)
  },
  computed: {
    // 生成桩强度等级
    powerLevelList() {
      var list = [],
        count = 15
      for (let i = 0; i <= 13; i++) {
        let itm = {}
        itm.title = 'C' + count
        itm.value = i
        count = count + 5
        list.push(itm)
      }
      return list
    },
  },
  
  props: {
    pileList: Array,
    height: {
      default: 432,
      type: Number,
    },
  },
}
</script>

原理:减少对DOM节点的渲染,通过滚动函数节流实现滚动后事件来动态渲染数据,编辑型表格不能直接全部显示出来,因为这样初次渲染节点很多,会卡。所以这里通过一点"障眼法"让用户觉得这个就是可输入的文本框(注意:别忘了设置autofocus,不然要双击才能输入,体验不是很好)。

可以看到,文本框被激活时这里通过添加"col--actived"类来动态渲染的
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352