一、需求如下:
根据用户输入生成多行可供编辑的表格,如下图:
根据用户输入的检测数量来显示表格行数
二、初步想法
根据用户输入对其绑定的数组新增行
// 根据检测数量和回填信息生成测点信息表
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>
可以看到,文本框被激活时这里通过添加"col--actived"类来动态渲染的原理:减少对DOM节点的渲染,通过滚动函数节流实现滚动后事件来动态渲染数据,编辑型表格不能直接全部显示出来,因为这样初次渲染节点很多,会卡。所以这里通过一点"障眼法"让用户觉得这个就是可输入的文本框(注意:别忘了设置autofocus,不然要双击才能输入,体验不是很好)。
网友评论