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