Element樹形控件Tree踩坑:修改current-node-key無效

業務場景

我司的在線網盤項目,彈窗裏要實現一個目錄樹,用於選擇文件要移動的目標路徑。
在這裏插入圖片描述

需求分析

  1. 點擊節點時,選中該節點
    1.1 如果該節點下有子節點,同時觸發展開(或收起)
  2. 點擊左邊樹節點圖標,展開節點時,選中該節點
  3. 點擊左邊樹節點圖標,收起節點時,選中該節點

總之,只要點擊在某一個節點所在行,都要選中該節點

踩坑實錄

在Element組件裏,Tree樹形控件算是相對複雜的一個,但是文檔卻很簡略,大部分API都沒有使用示例。講一下我遇到的問題。

  • 實現需求1,因爲 UI 同學沒有給複選框,所以要配置 check-on-click-node 參數實現點擊選中;同時使用 node-click 事件來監聽。但是自測發現,當點擊在左邊的節點展開/收起圖標上,不會觸發 click 事件。
  • 要想實現需求2,需要另外配置 node-expand 事件監聽
  • 同樣,實現需求3,需要另外配置 node-collapse 事件監聽

這樣,選中節點的三種觸發條件我們都考慮到了。下面賦值 data: currentNodeKey,保存當前選中節點的ID,並體現出選中狀態的高亮效果

  • current-node-key(當前選中的節點)
    這個參數有個問題:如果在 data 裏定義初始值,可以實現該id對應節點的默認選中高亮效果。但如果用 this.currentNodeKey = xx 再修改這個值,沒有任何變化。
  • setCurrentKey(通過 key 設置某個節點的當前選中狀態,使用此方法必須設置 node-key 屬性)
    繼續往下看文檔,找到這個 Tree 實例方法。先獲取 Tree 實例再調用該方法,雖然實現了修改選中狀態和高亮效果,但並沒有響應式地修改 currentNodeKey 的值。

也就是說,這兩個配置要同時存在才能實現完整的選中效果。一個改了 currentNodeKey 值,選中的樣式卻沒變;一個改了選中狀態的樣式效果,選中值卻沒變。

反人類啊有沒有???

好吧,反正element也不維護了,湊合用吧。測試出這些配置的實際效果,就可以愉快地填坑了,其實也很簡單,監聽 currentNodeKey 值的變化,再調用 setCurrentKey 方法就可以了。

關鍵代碼

<template>
	<div>
		...
		<el-tree ref="my-tree" :data="treeData" node-key="id" highlight-current check-on-click-node :current-node-key="currentNodeKey" @node-click="handleNodeClick" @node-expand="handleNodeExpand" @node-collapse="handleNodeCollapse" ></el-tree>
		...
	</div>
</template>
<script>
export default {
   
  watch: {
   
    currentNodeKey(id) {
   
    // Tree 內部使用了 Node 類型的對象來包裝用戶傳入的數據,用來保存目前節點的狀態。可以用 $refs 獲取 Tree 實例
      if (id.toString()) {
   
        this.$refs["my-tree"].setCurrentKey(id);
      } else {
   
        this.$refs["my-tree"].setCurrentKey(null);
      }
    }
  },
  data() {
   
    return {
   
      treeData: [],
      currentNodeKey: "" // 當前選中的節點(移動/複製到的目標文件夾id)
    };
  },
  methods: {
   
    // 節點被點擊時的回調
    // 共三個參數,依次爲:傳遞給 data 屬性的數組中該節點所對應的對象、節點對應的 Node、節點組件本身
    handleMoveCopyNodeClick(data) {
   
      this.currentNodeKey = data.id;
    },
    // 節點被展開時觸發的事件
    // 共三個參數,依次爲:傳遞給 data 屬性的數組中該節點所對應的對象、節點對應的 Node、節點組件本身
    handleMoveCopyNodeExpand(data) {
   
      this.currentNodeKey = data.id;
    },
    // 節點被關閉時觸發的事件
    // 共三個參數,依次爲:傳遞給 data 屬性的數組中該節點所對應的對象、節點對應的 Node、節點組件本身
    handleMoveCopyNodeCollapse(data) {
   
      this.currentNodeKey = data.id;
    },
    ...
  }
};
</script>

補充說明

實現並不完美。如果點擊的節點有子節點,會同時觸發 node-clicknode-expand / node-collapse 事件,造成多餘調用。
如果事件處理函數有賦值之外的其他副作用,會造成意想不到的bug,有這個需求的注意添加條件判斷一下。

Element 官網鏈接

Element Tree組件官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章