elementui tree回顯節點半選解決方案


問題分析
前端開發告訴我說【tree組件因為存了后台存儲了全部的節點,頁面回顯時,因為父節點的關系,把子節點也全部勾上了,現在沒法處理,必須要改接口加上半選節點的參數保存起來,再在回顯時調用接口獲取到半選的節點】。

不得不說,這的確是一個解決方案,但並不是一個好的解決方案。該接口固然能實現這個需求,但是要知道接口的改動會帶來一系列意想不到的變化,比如數據庫,緩存,接口參數和返回值,而且在已經集成好的接口上拓展新的變化,根據螺旋式開發規則的風險變化,BUG會隨着螺旋的增大而急劇增大。雖然這個問題比較小,只是多存儲了一些Service端用不上屬性而已,但只是因為組件升級或bug,就需要改動功能無問題的接口,這並不是好的開發模式。作為一名優秀的開發者,首先想到的是應該用自己的辦法去解決對接的問題,如果實在沒有辦法,再考慮兩端協調的修改。

從業務分析來看 Service不論是check還是halfCheck都是必要的數據。但view端需要區分check,halfCheck來顯示不同的圖標,這就很矛盾了,可目的也很明確前端需要區分出半選節點。

那么怎么改才是最合理的呢?當然是利用JS處理回顯的邏輯,這樣即使組件變化或BUG依舊不會去改變接口。如果通過改接口修正好了,那若控件升級或bug,難道還要一改再改接口嗎,當然不能。接口的設計不可能滿足所有組件的需求,但它一定滿足業務。既然可以通過自己控制,就沒有必要去做一些更繁瑣的工作,不是嗎?

廢話不多說了,下面看代碼!

解決方案

new Vue({
	el: '#app',
	data: function() {
		return {
			data: [{
				id: "1",
				label: '1',
				children: [{
					id: "2",
					label: '2-1',
					children: [{
						id: "21",
						label: '2-1-1'
					}, {
						id: "22",
						label: '2-1-2'
					}]
				}, {
					id: "3",
					label: '2-2',
					children: [{
						id: "31",
						label: '2-2-1'
					}, {
						id: "32",
						label: ' 2-2-2'
					}]
				}]
			}],
			checkStrictly: true,
			defaultProps: {
				children: 'children',
				label: 'label'
			}
		}
	},
	mounted() {
    var that = this;
    ["1", "2", "22", "3", "31","32"].forEach((i,n) => {
      var node = that.$refs.menuListTree.getNode(i);
      console.log(node.isLeaf)
      if(node.isLeaf){
        that.$refs.menuListTree.setChecked(node, true);
      }
    });
	}
});

  


實現原理
利用tree組件渲染后帶有的isLeaf(是否為葉子節點)屬性,如果為葉子節點就選中。這樣利用tree的API就實現了正確的回顯效果。並沒有過多的邏輯,只是利用tree本身的API 出BUG的概率也不會變高。手動設置node其實和prop的default-checked-keys原理是一樣的,其實內部也都是循環,也不會出現效率的問題。所處理的也只是多了一層isLeaf的判斷而已。

總結
我走過的彎路
看到的第一反應是之前遇到過,早些年在做ztree的時候也有這個問題,當時用API就解決了,el-tree應該也有。於是查了一大圈,發現有個函數叫setCheckedKeys(keys, leafOnly),設置leafOnly = false,就可以只設置子節點選中。以為有用,於是試了一下,發現果然是【子節點】選中啊…父節點一個都沒選,於是失敗了。
又找到一個屬性叫做 check-strictly,設置check-strictly = true,賦值結束后再重置check-strictly = false表面上看起來是好試了,但仔細點看發現【父節點】不是半選的!!!又失敗了…
說心里話,這點其實el-tree可能可以優化一下會更好,這個需求早在jquery的階段就有了,ztree就解決過。el做為更新的vue組件,應該早就能設想到這種情況了,但卻沒有提供回顯半選這樣的設置屬性或者函數,這也是美中不足的地方。

可愛的地方是即使如此,依然通過API的函數組合,可以達到想要的效果,雖然看起來不是特別優雅,好在沒有花太多力氣。

如果一個問題困擾自己很久,有幾種可能:

API了解不夠深入,並不熟練
走了彎路還不肯放棄,非要一條路走到黑,掉入自己畫的圈中無法跳出
確實無法通過現有的方法實現
正確的解決問題的方式是應該靈活多變的,開發更多的提倡解耦,面向對象,而不是面向過程。就好比考試的時候遇到一個問題,答案可能有很多種。但再多的答案,都需要自己作答,而並不是去修改題目、添加條件,當然若題目出錯了自然另當別論。答案的好壞才會關系到得分的高低,再多字數,再華麗的詞匯,卻沒有得分點,那依舊是不得分的。

就我自己而言,也經常一條路跑到黑,很容易掉進坑里。一般這時候會選擇仔細的查API和代碼,終會有所發現。要么就換思路,要么就換組件。引用一句不知道誰說的話“妄圖用代碼解決一切問題的人,最終都會失敗。”因為你所使用的庫,不可能全部是自己寫的,總會有自己的邏輯無法觸及的地方,難道遇到一個就要改一份源碼嗎?當然不能。^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM