一. 前言,最近接到一个需求,对树形结构的增加和修改展示为表格可以进行删除和查看(纯前端,没有后台接口调),如下图:图上的新增查看编辑和删除纯前端操作
-
新增的弹出新增经办机构的弹框并且对下面的树形结构数据进行保存到表格里面。(表格展示里面有一些条件列表:
1)选择的是整个省行显示【中国银行浙江省行】
2)选择的是分行显示【中国银行滨江分行】
3)选择的是支行显示【中国银行滨江信息港支行】
4)选择的是网点显示【中国银行信息港网点】
1.1 首先可以利用 @check="onCheck"的事件,拿到所有选择的经办机构的存进一个数组里面代码如下:
this.checkedNodeList = []
info.checkedNodes.filter(node => {
// 只追加存在的节点,最后一个节点
if (node.data.props.id) {
this.checkedNodeList.push(node.data.props.dataRef)
}
})
},
但是保存在table里面如果某一个parent下面的children全部勾选中,就只能展示该parent否则展示children,这样的话this.checkedNodeList并不满足于需求,就需要写一个js,代码如下:
export function arrayToJson(treeArray){
var r = [];
var tmpMap ={};
for (var i=0, l=treeArray.length; i<l; i++) {
// 以每条数据的id作为obj的key值,数据作为value值存入到一个临时对象里面
tmpMap[treeArray[i]["id"]]= treeArray[i];
}
for (i=0, l=treeArray.length; i<l; i++) {
var key=tmpMap[treeArray[i]["parentId"]];
//循环每一条数据的pid,假如这个临时对象有这个key值,就代表这个key对应的数据有children,需要Push进去
if (key) {
if (!key["children"].length){
key["children"] = [];
key["children"].push(treeArray[i]);
}else{
// key["children"].push(treeArray[i]);
}
} else {
//如果没有这个Key值,那就代表没有父级,直接放在最外层
r.push(treeArray[i]);
}
}
return r
}
this.checkedNodeList = arrayToJson(this.checkedNodeList)
1.2 表格的话利用a-table的树形结构表格展示:代码如下:
rowKey="id"
:expanded-row-keys.sync="expandedRowKeys"
:expandIcon="expandIcon"
:data-source="dataSource"
:columns="columns"
:pagination="{
total: dataSource.length,
onChange: pageNumber => {
this.selfCurrent = pageNumber
},
showQuickJumper: true,
showSizeChanger: true,
current: selfCurrent,
pageSize: selfPageSize,
pageSizeOptions: pageSizeOptions,
showTotal: (total, range) => {
return `共 ${total} 条记录`
},
onShowSizeChange: (pageNumber, pageSize) => {
this.selfPageSize = pageSize
this.selfCurrent = 1
}
}"
>
<span slot="number" slot-scope="text, record, index">{{
index + 1 + (selfCurrent - 1) * selfPageSize
}}</span>
<span slot="name" slot-scope="text">{{ text }}</span>
<a slot="userAccount" slot-scope="text, record">
<template v-if="record.children.length == 0">
<!-- {{ record.userAccount + '1' }} -->
<span v-for="(item, i) in record.userAccount" :key="item.id">
<span v-if="i <= 4" @click="_viewManager(record, 'child')">
{{ item.account }}[{{ item.name }}]
</span>
</span>
<span
v-if="record.userAccount.length == 0"
@click="_viewManager(record, 'child')"
>
无
</span>
<span v-if="record.userAccount.length > 5">...</span>
</template>
<span v-else @click="_viewManager(record, 'child')">
{{ record.userAccount.length ? '查看' : '' }}
<span
v-if="record.userAccount.length == 0"
@click="_viewManager(record, 'child')"
>
无
</span>
</span>
</a>
<span slot="action" slot-scope="record">
<a @click="_edit(record)">编辑</a>
<a-divider type="vertical" />
<a @click="_delete(record)">删除</a>
</span>
</a-table>
- 修改的话需要回显点击改行的经办机构。树的回显:代码如下
:tree-data="treeData"
:replace-fields="replaceFields"
checkable
@select="onSelect"
@check="onCheck"
v-model="selectedKeys"
>
<template slot="name" slot-scope="{ id, name }">
<span>[{{ id }}]{{ name }}</span>
</template>
</a-tree>
v-model="selectedKeys"拿到该行的机构ID去进行回显
2.1 新增的回显需要展示列表所有的机构:只需要把列表的机构的ID组成数组拿出来并且赋值给selectedKeys
- 删除就比较简单了利用数组filter,代码如下:
that.dataSource = that.dataSource.filter(item => {
return item.id != record.id
})
- 比较复杂的就是客户经理的查看,每个对应的机构下面有对用的客户经理,客户经理默认进去全部勾选,并且可以进行操作去勾选,而且此时传给后台的表格数据要删除对应的客户经理:如下图:
回显的时候需要不能去掉对应的客户经理而是去勾选,此时就要对比列表返回的数据的客户经理和tree上的机构对应的客户经理进行对比,列表机构对应的客户经理缺少的话就去勾选
getDiffArr(a, filterData) {
if (a.length == 0) {
return
}
// 找到当前节点下面的项目经理数
// 比较当前的节点和总的tree下面的项目经理
let diffArr = [...a[0].userAccount].filter(x =>
[...filterData].every(y => y.id !== x.id)
)
if (!diffArr.length) {
this.plainOptions = a[0].userAccount
this.currentSelectData = a[0]
this.managerCheckValue = this.plainOptions.map(item => item.id)
} else {
this.plainOptions = a[0].userAccount
this.currentSelectData = a[0]
let b = [...a[0].userAccount].filter(x =>
[...diffArr].every(y => y.id !== x.id)
)
this.managerCheckValue = b.map(item => item.id)
}
},
二. 总结一下:利用递归对树形结构的处理:
for (var j = 0; j < data.length; j++) {
data[j].disableCheckbox = type
if (data[j].children.length > 0) {
this.addAttr(data[j].children)
}
}
return data
},
这个是递归禁用复选框按钮的。
getCity(arr, data, city = []) {
if (typeof data === 'object') {
for (let i = 0; arr[i] !== undefined; i++) {
for (let j = 0; data[j] !== undefined; j++) {
if (arr[i] === data[j].id) {
city.push(data[j])
}
}
}
for (let i = 0; data[i] !== undefined; i++) {
this.getCity(arr, data[i].children, city)
}
}
return city
},
这个递归是查看只回显当前选中的机构
写在最后
文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
本文首发于掘金,未经许可禁止转载💌