背景 項目中用到了vue的element-ui框架,用到了el-tree組件。由於數據量很大,使用了數據懶載入模式,即非同步樹。非同步樹採用覆選框進行結點選擇的時候,沒法自動展開,官方文檔找了半天也沒有找到好的辦法! 找不到相關的配置,或者方法可以使用。 經過調試與閱讀elment-ui源碼才發現有現成 ...
背景
項目中用到了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']