一、功能说明
1. 效果图
2. 说明
- 新增:新增表格父行
- 新增:新增表格子行
- 删除:删除父行
- 更多下拉菜单(上移):上移父行 / 子行
- 更多下拉菜单(下移):下移父行 / 子行
- 编辑:父行只有名称列可编辑,子行没有限制。触发方式为点击单元格。
二、实现
<template>
<div class="box">
<span @click="addParent" style="margin-bottom:5px">
<a-icon type="plus-circle" style="margin-right:5px" />新增
</span>
<a-spin :spinning="spinning">
<vxe-table
border
resizable
auto-resize
show-overflow
highlight-hover-row
highlight-current-row
ref="xTable"
row-id="id"
max-height="500px"
:data="tableData"
:edit-config="{
trigger: 'click',
mode: 'cell',
activeMethod: activeMethod
}"
:tree-config="{ children: 'children' }"
>
<vxe-column field="name" title="名称" :edit-render="{}" tree-node>
<template #edit="{ row }">
<vxe-input v-model="row.name" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="code" title="代号" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.code" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column field="condition" title="条件" :edit-render="{}">
<template #edit="{ row }">
<vxe-input v-model="row.condition" type="text"></vxe-input>
</template>
</vxe-column>
<vxe-column title="操作" fixed="right">
<template #default="{ row,rowIndex }">
<!-- 父行操作按钮 -->
<span v-if="'children' in row">
<span @click="addChild(row, rowIndex)" class="op-btn">新增</span>
<span @click="deleteParent(row, rowIndex)" class="op-btn">删除</span>
<a-dropdown :trigger="['click']">
<a @click.prevent>
<a-icon type="dash" style="color:black;transform: rotate(90deg);" />
</a>
<template #overlay>
<a-menu>
<a-menu-item :key="0" @click="upRow(row, rowIndex)">上移</a-menu-item>
<a-menu-item :key="1" @click="downRow(row, rowIndex)">下移</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</span>
<!-- 子行操作按钮 -->
<span v-else>
<span @click="deleteChild(row, rowIndex)" class="op-btn">删除</span>
<span @click="upRow(row, rowIndex)" class="op-btn">上移</span>
<span @click="downRow(row, rowIndex)" class="op-btn">下移</span>
</span>
</template>
</vxe-column>
</vxe-table>
</a-spin>
</div>
</template>
<script>
export default {
data() {
return {
spinning: false,
tableData: [],
moveArray: []
}
},
async created() {
await this.getTableData()
},
methods: {
async getTableData() {
this.spinning = true
this.tableData = [
{
creator: '小红',
code: 'xh',
name: '工艺1',
description: '',
condition: '',
id: 1,
children: [
{
creator: '红红',
code: 'hh',
name: '工艺11',
condition: '',
description: '',
id: 11
},
{
creator: '花花',
code: 'hh',
name: '工艺12',
condition: '',
description: '',
id: 12
},
{
creator: 'aa',
code: 'hh',
name: '工艺13',
condition: '',
description: '',
id: 13
}
]
},
{
creator: '小蓝',
code: 'xl',
name: '工艺2',
description: '',
condition: '',
id: 2,
children: [
{
creator: '蓝蓝',
code: 'll',
name: '工艺22',
condition: '',
description: '',
id: 21
}
]
},
{
creator: '小白',
code: 'xb',
name: '工艺3',
condition: '',
description: '',
id: 3,
children: []
}
]
this.spinning = false
},
addParent() {
const record = {
name: '',
code: '',
condition: '',
id: this.getGUID(),
children:[]
}
this.tableData.push(record)
this.$message.success('新增成功!')
},
deleteParent(row, rowIndex) {
this.tableData.splice(rowIndex, 1)
this.$message.success('删除成功!')
},
deleteChild(row) {
let info = this.findChildIndex(this.tableData, row.id)
this.tableData[info[1]].children.splice(info[0], 1)
this.$message.success('删除成功!')
},
downRow(row, rowIndex) {
let index = rowIndex
this.moveArray = this.tableData
if ('children' in row === false) {
let info = this.findChildIndex(this.tableData, row.id)
index = info[0]
this.moveArray = this.tableData[info[1]].children
}
if (index === this.moveArray.length - 1) {
this.$message.warning('此行不能下移!')
} else {
this.moveArray = this.swapItem(this.moveArray, index, index + 1)
this.$message.success('下移成功!')
}
},
upRow(row, rowIndex) {
let index = rowIndex
this.moveArray = this.tableData
if ('children' in row === false) {
let info = this.findChildIndex(this.tableData, row.id)
index = info[0]
this.moveArray = this.tableData[info[1]].children
}
if (index === 0) {
this.$message.warning('此行不能上移!')
} else {
this.moveArray = this.swapItem(this.moveArray, index, index - 1)
this.$message.success('上移成功!')
}
},
swapItem(arr, index1, index2) {
arr[index1] = arr.splice(index2, 1, arr[index1])[0]
return arr
},
activeMethod({ row, column }) {
let tag =
'children' in row &&
['code', 'condition'].includes(column.property)
return !tag
},
addChild(row, rowIndex) {
const record = {
name: '',
code: '',
condition: '',
description: '',
id: this.getGUID()
}
this.tableData[rowIndex].children.push(record)
this.$message.success('新增成功!')
},
findChildIndex(data, id) {
let result = []
function find(data, id, parentId) {
for (let i = 0; i < data.length; i++) {
if (result.length > 0) {
return
}
if (data[i].id === id) {
result.push(i)
result.push(parentId)
}
if (data[i].children && data[i].children.length > 0) {
find(data[i].children, id, i)
}
}
}
find(data, id, 0)
return result
},
getGUID() {
var d = new Date().getTime()
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
/[xy]/g,
function (c) {
var r = (d + Math.random() * 16) % 16 | 0
d = Math.floor(d / 16)
return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16)
}
)
return uuid
}
}
}
</script>
<style>
.box {
width: 1000px;
margin: 100px;
}
.op-btn {
margin: 0 2px;
cursor: pointer;
}
</style>
三、导入