背景
项目中用到了vue的element-ui框架,用到了el-tree组件。由于数据量很大,使用了数据懒加载模式,即异步树。异步树采用复选框进行结点选择的时候,没法自动展开,官方文档找了半天也没有找到好的办法! 找不到相关的配置,或者方法可以使用。 经过调试与阅读elment-ui源码才发现有现成的方法可以进行结点展开。下面就介绍结点展开的实现!
1.监听复选框点击事件check
<el-tree :props="mulprops" :load="loadNode" lazy node-key="id" show-checkbox accordion @current-change="currentChange" :filter-node-method="filterNode" @check="handleCheck" ref="tree" :default-checked-keys="defaultCheckedNodes" :default-expanded-keys="defaultExpandedNodes" > </el-tree>
2.手动展开,使用node.expand()方法
handleCheck(nodeData, treeChecked) { let node = this.$refs.tree.getNode(nodeData.id) //将选中的未展开的节点进行展开 if(node.checked && !node.expanded){ node.expand(function(){ for(let i=0; i< node.childNodes.length; i++){ node.childNodes[i].expand() } }) } }
项目中的实现
一、复选框勾选后能自动展开并选中,先展开再勾选也可以自动展开
1.监听check-change事件
<el-tree :props="mulprops" :load="loadNode" lazy node-key="id" show-checkbox accordion @check-change="handleCheckChange" :filter-node-method="filterNode" ref="tree" :default-checked-keys="defaultCheckedNodes" :default-expanded-keys="defaultExpandedNodes" > </el-tree>
2.编写展开勾选结点方法
handleCheckChange(nodeData, nodeSelected) { let tree = this.$refs.tree; let node = tree.getNode(nodeData.id) //展开选中的未展开的节点 this.expandCheckedNotExpandNodes(node); //具体业务实现 console.log(nodeData, nodeSelected) }, //展开选中的未展开的节点 expandCheckedNotExpandNodes(node) { let tree = this.$refs.tree; if (node.checked && !node.expanded && !node.isLeaf) { node.expand(function () { let childNodes = node.childNodes; for (let i = 0; i < childNodes.length; i++) { let childNode = childNodes[i]; //手动触发check-change事件,事件处理函数中回继续调用此函数,形成递归展开 tree.$emit('check-change', childNode.data, childNode.checked, childNode.indeterminate); } }) } },
二、 展开指定结点
<el-input type="text" v-model='nodeDataIds' placeholder="请输入结点数据ID(多个以逗号分割)"> ></el-input> <el-button type="primary" @click="expandNodes(nodeDataIds.split(','))">展开指定结点</el-button>
//展开匹配的结点,根结点默认展开 expandNodes(nodeDataIds){ let that = this; let tree = this.$refs.tree; let rootNode = tree.root; //展开一层结点函数 let expandRootChildren = function(){ let childNodes = rootNode.childNodes; for (let i = 0; i < childNodes.length; i++) { let childNode = childNodes[i]; that.expandNode(childNode,nodeDataIds); } }; //根结点未展开进行展开 if(!rootNode.expanded){ rootNode.expand(function(){ //展开根结点的孩子 expandRootChildren(); }); }else{ //展开根结点的孩子 expandRootChildren(); } }, //展开指定结点下匹配的结点 expandNode(node, nodeDataIds){ let that = this; //当前结点需要展开未展开,则展开 if(nodeDataIds.indexOf(node.data.id) != -1){ //孩子结点需要展开未展开,则展开 let expandChildren = function(){ let childNodes = node.childNodes; for (let i = 0; i < childNodes.length; i++) { let childNode = childNodes[i]; //递归展开孩子结点 that.expandNode(childNode, nodeDataIds); } } if(!node.expanded){ node.expand(function(){ expandChildren(); }); }else{ expandChildren(); } } },
三. 勾选指定结点
1.异步树,需先展开指定结点,然后有数据了才能勾选上(即:展开父结点,子节点有了数据才能勾选上)
<el-button type="primary" @click="checkNodes(nodeDataIds.split(','))">选中指定结点</el-button>
checkNodes(nodeDataIds){
let tree = this.$refs.tree;
tree.setCheckedKeys(nodeDataIds, false)
}
2.设置默认勾选的结点,首次展开会自动勾选上,适合写数据回显
default-checked-keys=['node001','node002']