如图,同事让帮忙实现一个需求
从二级树节点开始,同时选中的只能有一个二级树节点,选中的二级树节点之下的子节点都可以被选中。否则不能被选中
直接上代码
需要注意的是,文中树状图传递的数据是打平的数据,设置代码是下图,而不是树状图!!
javascript
:tree-config="{transform: true, rowField: 'cguid', parentField: 'cparentid'}"
上述的这一点非常重要
下面的全乎的数据图
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<!-- 引入样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vxe-table@legacy/lib/style.css">
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<!-- 引入组件 -->
<script src="https://cdn.jsdelivr.net/npm/xe-utils"></script>
<script src="https://cdn.jsdelivr.net/npm/vxe-table@3.6.9"></script>
<script src="data.js"></script>
</head>
<body>
<div id="app">
<vxe-table ref="treeNode" resizable :tree-config="{transform: true, rowField: 'cguid', parentField: 'cparentid'}" :data="tableData"
:checkbox-config="{labelField: 'cguid', highlight: true,visibleMethod:()=>true,checkMethod:()=>true}"
@checkbox-change="selectChangeEvent">
<vxe-column type="checkbox" title="ID" width="280" tree-node></vxe-column>
<vxe-column field="cname" title="Name"></vxe-column>
</vxe-table>
</div>
</body>
1:删除
2:节点禁用
3:筛选
<script>
new Vue({
el: '#app',
data: function () {
return {
tableData: [],
chooseDataTree: null,//选中的树节点的内容
data2tree: [],//将打平数据封装成树结构
}
},
created() {
this.tableData = dataList;
//将数据改为树状结构
children = getJsonTree(dataList, '000000');
//遍历需要这种结构
this.data2tree = {
cguid: "000000",
children,
}
},
methods: {
selectChangeEvent({ $table, indeterminates, row, records }) {
console.log(arguments)
//将当前选中的数据 被选中子节点到root的数据
this.handleCheckChange([...records, ...indeterminates],row)
},
handleCheckChange(data,row) {
//整理成树状图
let chooseTree = getJsonTree(data, '000000')
//当前选中节点是不是在第一次选中的树节点中
let bool = this.checkMethod({row,chooseTree,chooseList:data})
console.log('bool:',bool)
//不再就不让勾选,同时提示
if(!bool){
this.$refs.treeNode.setCheckboxRow(row,false)
VXETable.modal.message('当前无法被选中')
}
},
checkMethod({ chooseList,row ,chooseTree}) {
//有选中的数据
if (chooseList.length > 0 ) {
//已经存在选中的tree
if(this.chooseDataTree){
//已经选中的tree中是否存在当前选中的项
let haveBool = hasChildNode(this.chooseDataTree, row.cguid);
return haveBool
}
//获取选中的树表格
let chooseTreeData = chooseTree[0];
//从树表格中获取第二级的节点(只有选中节点数据)
let leve2Item = chooseTreeData.children[0];
//从完整的树表中获取完整的指定节点数据
let getThenTree = getLeafNode(this.data2tree, leve2Item.cguid);
//将选中的二级节点保存起来 用于校验
this.setChooseDataTree(getThenTree);
//检查当前节点是不是在选中的二级节点之中
let haveBool = hasChildNode(getThenTree, row.cguid);
console.log('getThenTree:',getThenTree.cname,getThenTree);
console.log('row:',row.cname,row)
return haveBool
} else {
console.log('选中的内容空空如也')
//将选中内容置空
this.setChooseDataTree(null);
return true
}
},
//设置选中后的数据内容
setChooseDataTree(data){
this.chooseDataTree = data
}
}
})
//讲打平的数据组将组为树状图
function getJsonTree(data, cparentid) {
var result = [], temp;
for (var i = 0; i < data.length; i++) {
if (data[i].cparentid == cparentid) {
if (cparentid === "000000") data[i]['disabled'] = true;
var obj = { "name": data[i].cname, "id": data[i].cguid };
obj = Object.assign(obj, data[i]);
temp = this.getJsonTree(data, data[i].cguid);
if (temp.length > 0) {
obj.children = temp;
}
result.push(obj);
}
}
return result;
}
//指定的节点中是否包含相应的子节点
function hasChildNode(root, cguid) {
if (root == null) {
return false;
}
if (root.cguid === cguid) {
return true;
}
let found = false;
if (root.children && root.children.length > 0) {
root.children.forEach(child => {
if (hasChildNode(child, cguid)) {
found = true;
}
});
}
return found;
}
//从树的表格中获取指定字节点内容数据
function getLeafNode(root, cguid) {
if (root == null) {
return null;
}
if (root.cguid == cguid) {
return root;
}
let result = null;
if (root.children && root.children.length > 0) {
root.children.forEach(child => {
const leafNode = getLeafNode(child, cguid);
if (leafNode != null) {
result = leafNode;
}
});
}
return result;
}
</script>
</html>
json打平的数据结构是
javascript
const dataList = [
{
"cguid": "5422",
"ccode": "01",
"cname": "01 资产",
"cparentid": "000000",
"ileaf": "0"
},
{
"cguid": "70",
"ccode": "1004",
"cname": "1004 汇总科目",
"cparentid": "5422",
"ileaf": "0"
},
{
"cguid": "78",
"ccode": "100401",
"cname": "100401 汇总科目1",
"cparentid": "70",
"ileaf": "1"
},
{
"cguid": "95",
"ccode": "100402",
"cname": "100402 汇总科目2",
"cparentid": "70",
"ileaf": "1"
},
{
"cguid": "47",
"ccode": "100403",
"cname": "100403 汇总科目3",
"cparentid": "70",
"ileaf": "1"
},
{
"cguid": "87",
"ccode": "100404",
"cname": "100404 汇总科目4",
"cparentid": "70",
"ileaf": "0"
},
{
"cguid": "97",
"ccode": "10040401",
"cname": "10040401 汇总科目4-1",
"cparentid": "87",
"ileaf": "1"
},
{
"cguid": "41",
"ccode": "90000201",
"cname": "90000201 B2c1",
"cparentid": "31",
"ileaf": "1"
},
{
"cguid": "77",
"ccode": "90000202",
"cname": "90000202 B2c2",
"cparentid": "31",
"ileaf": "1"
},
{
"cguid": "428",
"ccode": "1001",
"cname": "1001 库xxx",
"cparentid": "422",
"ileaf": "1"
},
{
"cguid": "430",
"ccode": "1002",
"cname": "1002 银xxx",
"cparentid": "422",
"ileaf": "1"
},
]