element-ui tree 异步树实现勾选自动展开、指定展开、指定勾选

背景

项目中用到了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; this .expandNode(rootNode, nodeDataIds);
},
// 展开指定结点下匹配的结点 expandNode(node, nodeDataIds){
let that
= this ; // 当前结点需要展开未展开,则展开(根结点默认展开) if (node.level==0 || 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  > 
    
  
expandNodes(nodeDataIds)
展开完成的时机比较难判断
 checkNodes(nodeDataIds){
let tree = this.$refs.tree;
tree.setCheckedKeys(nodeDataIds, false)
}

 2.设置默认勾选的结点,再调用展开方法会自动勾选上,适合写数据回显

 default -checked-keys=['node001','node002']
expandNodes(nodeDataIds)

 

四、展开并勾选结点(支持异步树)牛逼版,实现展开回调

 //  展开匹配的结点,根结点默认展开 
 expandNodes(nodeDataIds){
let that
= this ;
let tree
= this .$refs.tree;
let rootNode
= tree.root; this .expandNode(rootNode, nodeDataIds, function (){
that.checkNodes([
'node001','node002' ]);
});
},
// 展开指定结点下匹配的结点 expandNode(node, nodeDataIds, callback){
let that
= this ; // 递归进入 that.recursiveEnter(); // 当前结点需要展开未展开,则展开(根结点默认展开) if (node.level==0 || nodeDataIds.indexOf(node.data.id) != -1 ){ // 展开孩子结点 let expandChildren = function (){
let childNodes
= node.childNodes; if (childNodes.length > 0 ){ for (let i = 0; i < childNodes.length; i++ ) {
let childNode
= childNodes[i]; // 递归展开孩子结点 that.expandNode(childNode, nodeDataIds, callback);
}
}
}
if (! node.expanded){ // 当前结点未展开则先展开,展开后再展开孩子结点 node.expand( function (){ // 展开孩子结点 expandChildren(); // 递归退出 that.recursiveExit(callback);
});
}
else { // 当前结点已展开,直接展开孩子结点 expandChildren(); // 递归退出 that.recursiveExit(callback);
}
}
else { // 递归退出 that.recursiveExit(callback);
}
},
// 递归计入计数剩余递归次数 recursiveEnter(){ this .recursiveRemainCount++ ;
console.log(
'enter recursiveRemainCount', this .recursiveRemainCount)
},
// 递归退出计数剩余递归次数 recursiveExit(callback){ this .recursiveRemainCount-- ;
console.log(
'exit recursiveRemainCount', this .recursiveRemainCount) if ( this .recursiveRemainCount==0 ){ if (callback){
callback();
}
}
},
checkNodes(nodeDataIds){
let tree
= this .$refs.tree;
tree.setCheckedKeys(nodeDataIds,
false )
}

 

标签: Javascript

添加新评论