[http://www.umyui.com/umycomponent/basicEditTable]umy-ui虚拟表格
<template>
<div class="final-accounts-view">
<ux-grid
class="task-table"
ref="plxTable"
size="mini"
show-overflow
widthResize
:data="taskTemplateList"
:span-method="objectSpanMethod"
:highlightCurrentRow="false"
:edit-config="{ trigger: 'click', mode: 'cell',showIcon:false}"
border
style="width: 100%"
>
<ux-table-column field="primaryNumber" title="一级编号" fixed="left"></ux-table-column>
<ux-table-column field="firstLevelTask" title="一级名称" fixed="left"></ux-table-column>
<ux-table-column field="secondaryNumber" title="二级编号">
<template v-slot="{row}">
<div class="add-position">
<span>{{ row.secondaryNumber }}</span>
<i v-if="showAddIcon(row,2)" class="h-icon-circle-plus-fill cp" @click.stop="addItem(row,2)"></i>
</div>
</template>
</ux-table-column>
<ux-table-column field="secondaryTask" title="二级名称" :edit-render="{ autofocus: '.el-input__inner' }">
<template v-slot:edit="{row}">
<el-input v-model="row.secondaryTask" maxlength="500" @change="secondaryTaskChange(row)"/>
</template>
<template v-slot="{row}">
<span class="my-input-sc">{{ row.secondaryTask }}</span>
</template>
</ux-table-column>
<ux-table-column field="thirdLevelNumber" title="三级编号">
<template v-slot="{row}">
<div class="add-position">
<span>{{ row.thirdLevelNumber }}</span>
<i v-if="showAddIcon(row,3)" class="h-icon-circle-plus-fill cp" @click.stop="addItem(row,3)"></i>
</div>
</template>
</ux-table-column>
<ux-table-column field="levelThirdTask" title="三级名称" :edit-render="{ autofocus: '.el-input__inner' }">
<template v-slot:edit="{row}">
<el-input v-model="row.levelThirdTask" maxlength="500"/>
</template>
<template v-slot="{row}">
<span class="my-input-sc">{{ row.levelThirdTask }}</span>
</template>
</ux-table-column>
<ux-table-column title="操作" width="60">
<template v-slot="{row}">
<el-button
type="text"
@click="delItem(row)"
v-if="showAddIcon(row,3)"
>删除</el-button
>
</template>
</ux-table-column>
</ux-grid>
</div>
</template>
<script>
export default {
data () {
return {
taskDefault:[
{primaryNumber:'A',firstLevelTask:'A',secondaryNumber:'A-01',secondaryTask:'',thirdLevelNumber:'A-01-001',levelThirdTask:''},
{primaryNumber:'B',firstLevelTask:'B',secondaryNumber:'B-01',secondaryTask:'',thirdLevelNumber:'B-01-001',levelThirdTask:''},
{primaryNumber:'C',firstLevelTask:'C',secondaryNumber:'C-01',secondaryTask:'',thirdLevelNumber:'C-01-001',levelThirdTask:''},
],
primaryNumber:[],
firstLevelTask:[],
secondaryNumber:[],
secondaryTask:[],
taskTemplateList:[],
trigger:'manual',
}
},
mounted(){
this.taskTemplateList = JSON.parse(JSON.stringify(this.taskDefault))
this.rowSpan(this.taskTemplateList)
},
methods: {
showAddIcon(row,lv){
const index = this.taskTemplateList.map(item => item._XID).indexOf(row._XID);
if(lv==2){
const arr = this.taskTemplateList.filter(item => item.primaryNumber === row.primaryNumber)
const last = arr[arr.length -1]
const lastSameNum = arr.filter(item => item.secondaryNumber === last.secondaryNumber)
if(arr.indexOf(row) === (arr.length - lastSameNum.length)) {
return true
}
}
if(lv==3 && (index===(this.taskTemplateList.length-1)||this.taskTemplateList[(index+1)].secondaryNumber!= row.secondaryNumber)){
return true
}
},
getContractNumber (lv,levStart) {
let len = 1;
if (this.taskTemplateList && this.taskTemplateList.length) {
const arr = this.taskTemplateList.map(val => {
let row = JSON.parse(JSON.stringify(val))
if(lv===2 && val.primaryNumber==levStart){
let rowArr = row.secondaryNumber.split('-')
return rowArr[1]
}else{
if(lv===3 && val.secondaryNumber == levStart){
let rowArr = row.thirdLevelNumber.split('-')
return rowArr[2]
}else{
return 0
}
}
});
let max = 0;
if (arr.length) {
max = Math.max.apply(null, arr);
}
len = max + 1;
}
if(lv===2){
if (len >= 100) {
return `${levStart}-${len}`
} else if (len >= 10) {
return `${levStart}-${len}`
} else {
return `${levStart}-0${len}`
}
}
if(lv===3){
if (len >= 100) {
return `${levStart}-${len}`
} else if (len >= 10) {
return `${levStart}-0${len}`
} else {
return `${levStart}-00${len}`
}
}
},
secondaryTaskChange(row){
const secondaryRow = this.taskTemplateList.filter(item => item.secondaryNumber == row.secondaryNumber)
secondaryRow.forEach(item=>{
item.secondaryTask = row.secondaryTask
})
},
addItem (row,lv) {
const index = this.taskTemplateList.map(item => item._XID).indexOf(row._XID);
let addNum = index+1
let secondaryNumber = lv==3?row.secondaryNumber:this.getContractNumber(2,row.primaryNumber)
let secondaryTaskName = ''
const secondaryRow = this.taskTemplateList.filter(item => item.secondaryNumber == row.secondaryNumber)
if(lv===2){
addNum = index + secondaryRow.length
}
if(lv===3){
secondaryTaskName = row.secondaryTask
}
this.taskTemplateList.splice(addNum, 0, {
primaryNumber: row.primaryNumber,
firstLevelTask: row.firstLevelTask,
secondaryNumber: secondaryNumber ,
secondaryTask: secondaryTaskName,
thirdLevelNumber: this.getContractNumber(3,secondaryNumber),
levelThirdTask: ''
})
this.rowSpan(this.taskTemplateList)
},
delItem (rowObj) {
const index = this.taskTemplateList.map(item => item._XID).indexOf(rowObj._XID);
const surplusArr = this.taskTemplateList.filter(item=>(item.primaryNumber===rowObj.primaryNumber))
if(surplusArr.length==1){
return this.messageInfo('warning', '该编号最后一条数据不允许删除!')
}
this.$confirm('确定要删除该条数据吗?', '提示', {
confirmButtonText: '确 定',
cancelButtonText: '取 消',
type: 'question'
}).then(() => {
this.taskTemplateList.splice(index, 1)
this.rowSpan(this.taskTemplateList)
}).catch(() => { });
},
rowSpan (list) {
this.primaryNumber = []
this.firstLevelTask = []
this.secondaryNumber = []
this.secondaryTask = []
let contactDot = 0;
let contactDotTow = 0;
let contactDotThree = 0;
let contactDotFour = 0;
list.forEach((item, index) => {
if (index === 0) {
this.primaryNumber.push(1)
this.firstLevelTask.push(1)
this.secondaryNumber.push(1)
this.secondaryTask.push(1)
} else {
if (item.primaryNumber === list[index - 1].primaryNumber) {
this.primaryNumber[contactDot] += 1;
this.primaryNumber.push(0)
this.firstLevelTask[contactDotTow] += 1
this.firstLevelTask.push(0)
} else {
this.primaryNumber.push(1)
contactDot = index
this.firstLevelTask.push(1)
contactDotTow = index
}
if (item.primaryNumber === list[index - 1].primaryNumber && item.secondaryNumber === list[index - 1].secondaryNumber) { //第三列合并相同
this.secondaryNumber[contactDotThree] += 1
this.secondaryNumber.push(0)
this.secondaryTask[contactDotFour] += 1
this.secondaryTask.push(0)
} else {
this.secondaryNumber.push(1)
contactDotThree = index
this.secondaryTask.push(1)
contactDotFour = index
}
}
})
},
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (this.primaryNumber[rowIndex]) {
return {
rowspan: this.primaryNumber[rowIndex],
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
if (columnIndex === 1) {
if (this.firstLevelTask[rowIndex]) {
return {
rowspan: this.firstLevelTask[rowIndex],
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
if (columnIndex === 2) {
if (this.secondaryNumber[rowIndex]) {
return {
rowspan: this.secondaryNumber[rowIndex],
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
if (columnIndex === 3) {
if (this.secondaryTask[rowIndex]) {
return {
rowspan: this.secondaryTask[rowIndex],
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
},
}
}
</script>
<style lang="scss">
.final-accounts-view {
.my-input-sc {
display: inline-block;
height: 28px;
line-height: 25px;
-webkit-appearance: none;
background-color: #ffffff;
background-image: none;
border-radius: 4px;
border: 1px solid #dcdfe6;
box-sizing: border-box;
color: #606266;
font-size: 12px;
outline: none;
padding: 0 8px;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.task-table {
.el-input{
width: 100%;
}
.elx-table .elx-body--column, .elx-table .elx-footer--column, .elx-table .elx-header--column{
line-height: 26px;
}
.elx-cell{
height: 28px;
position: relative;
}
.elx-table--empty-block{
height: 300px;
}
.add-position {
display: flex;
justify-content: space-between;
align-items: center;
.h-icon-circle-plus-fill {
color: #0776d8;
padding-left: 8px;
}
}
.el-form-item {
width: 100%;
}
.el-table .cell {
width: 100% !important;
}
}
.elx-table--body-wrapper{
overflow-x: hidden;
}
.task_template_dialog{
.el-form{
.el-input{
width: 230px !important;
}
}
}
}
</style>