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)
    }

到此這篇關於element-ui tree 異步樹實現勾選自動展開、指定展開、指定勾選的文章就介紹到這瞭,更多相關element-ui tree 異步樹內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: