原先的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 优化成任意级别的目录(原先代码不兼容只有二级类目的)