原先的elementUI中tree組件原生的check-strictly未false屬性只能實現子節點選中時父節點默認選中,然后在保存的時候需要getHalfCheckedKeys()方法去獲取半選中狀態的父節點,然后在頁面渲染的時候,父節點由半選中變成了全選中,導致頁面菜單顯示錯誤(保存的時候子節點沒有全部選中,保存重新渲染會變成子節點全部默認選中)因此只能通過不關聯,然后自己實現關聯。代碼如下:
<el-tree :data="item.childAuthItem" show-checkbox ref="tree" node-key="id" @check="clickTree" :expand-on-click-node="false" :check-strictly="true" :props="defaultProps" ></el-tree> clickTree(curData, treeStatus) { const me = this; me.clickCheck(curData, treeStatus, me.$refs.tree) }, /** * 樹形菜單復選框父子節點不關聯實現父子節點聯動回顯 * * @see selectedParent - 處理父節點為選中 * @see uniteChildSame - 處理子節點為相同的勾選狀態 * @see removeParent - 子節點全沒選中取消父級的選中狀態 * * @param {Object} currentObj - 當前勾選節點的對象 * @param {Object} treeStatus - 樹目前的選中狀態對象 * @param {Object} ref - this.$refs.xxx **/ clickCheck(currentObj, treeStatus, ref) { // 用於:父子節點嚴格互不關聯時,父節點勾選變化時通知子節點同步變化,實現單向關聯。 let selected = treeStatus.checkedKeys.indexOf(currentObj.id); // -1未選中 // 選中 if (selected !== -1) { // 子節點只要被選中父節點就被選中 this.selectedParent(currentObj, ref); // 統一處理子節點為相同的勾選狀態 this.uniteChildSame(currentObj, true, ref); } else { // 取消子節點的選中狀態觸發 if (currentObj.parentId !== -1) { this.removeParent(currentObj, ref); } // 未選中 處理子節點全部未選中 if (currentObj.children && currentObj.children.length !== 0) { this.uniteChildSame(currentObj, false, ref); } } }, /** 統一處理子節點為相同的勾選狀態 **/ uniteChildSame(treeList, isSelected, ref) { let treeListData = treeList.children; let len if (treeListData && treeListData.length) { len = treeListData.length } else { len = 0 } ref.setChecked(treeList.id, isSelected); for (let i = 0; i < len; i++) { this.uniteChildSame(treeListData[i], isSelected, ref); } }, /** 統一處理父節點為選中 **/ selectedParent(currentObj, ref) { // console.log(ref) let currentNode = ref.getNode(currentObj); if (currentNode.parent.key !== undefined) { ref.setChecked(currentNode.parent, true); return this.selectedParent(currentNode.parent, ref); } }, /** 子節點全沒選中取消父級的選中狀態 **/ removeParent(currentObj, ref) { let a = 0; let b = 0; let currentNode = ref.getNode(currentObj); if (currentNode.parent !== null) { if (currentNode.parent.key !== undefined) { ref.setChecked(currentNode.parent, true); //根節點 this.removeParent(currentNode.parent, ref); //遞歸判斷子節點 } } //不為0表示為父節點 if (currentNode.childNodes && currentNode.childNodes.length !== 0) { //循環判斷父節點下的子節點 for (let i = 0; i < currentNode.childNodes.length; i++) { //判斷父節點下的子節點是否全為false if (currentNode.childNodes[i].checked === false) { ++a; //a === currentNode.childNodes.length 表明子節點全為false if (a === currentNode.childNodes.length) { //等於 undefined 跳過,不等於繼續執行 if (currentNode.childNodes[i].parent.key !== undefined) { ref.setChecked(currentNode.childNodes[i].parent, false); //父元素設置為false //循環上級父節點下的子節點 for (let i = 0; i < currentNode.parent.childNodes.length; i++) { //判斷父節點下的子節點是否全為false if (currentNode.parent.childNodes[i].checked === false) { ++b; //b === currentNode.parent.childNodes.length 表明子節點全為false if (b === currentNode.parent.childNodes.length) { ref.setChecked(currentNode.parent.key, false); //父元素設置為false return this.removeParent(currentNode.parent, ref); //繼續遞歸循環判斷 } } } } } } } } }
本代碼來自
https://blog.csdn.net/Beam007/article/details/87858291 優化成任意級別的目錄(原先代碼不兼容只有二級類目的)