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

作者: 不语u | 来源:发表于2020-09-07 17:42 被阅读0次

一、需求如下:

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


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

二、初步想法

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

// 根据检测数量和回填信息生成测点信息表
    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"类来动态渲染的

相关文章

网友评论

    本文标题:vue(element-ui)表格数据量多卡死

    本文链接:https://www.haomeiwen.com/subject/kcslektx.html