前言:el-tree使用懒加载方式(由于数据量大)设置默认选中的是父节点的前两个子节点,展开时,发现父节点和所有子节点全选中了,于是打了一下debugger,发现点击展开时,默认走选中的前两个子节点,到第二个节点是时走了reInitChecked方法,父节点的checked属性变成了true,因为父节点变成了true,所以他又将所有子节点都变成了true(莫名其妙子节点还没渲染完就重置了父节点的状态);然后我尝试了一下默认选中父节点的第一个和第三个节点,发现没有问题呢!???
首先我是使用懒加载的方式加载:简单写了个demo
createSignalLoadNodes (node, resolve) {
let that = this
let organId = node.data && node.data.organId ? node.data.organId : ""
this.organService.getOrganChildren(organId, function (res) {
if (res) {
let cloneTreeData = that.convertTreeData(res)
let time = arr.length + 200
//这个方法重置节点状态
this.setChildNodeChecked(node, time)
resolve(cloneTreeData)
}
})
}
使用setChildNodeChecked方法重置节点选中状态
setChildNodeChecked (node, time) {
setTimeout(() => {
node.childNodes && node.childNodes.forEach(cell => {
if (! this.defaultCheckedKeys.find(val => val == cell.data.id)) {
cell.checked = false
//本来想的是如果子节点有不选中的就给父节点添加半选
// node.indeterminate = true
} else {
cell.checked = cell.checked
}
//重置半选
this.addSelectChecked()
});
}, time)
}
发现子节点的状态对了,但是父节点还是勾选状态,于是在给子节点false的时候给父节点添加半选发现不起作用于是新写了一个方法addSelectChecked
addSelectChecked () {
let tree: any = this.$refs.signalTree
this.$nextTick(() =>{
if (tree) {
this.halfCheckedIds.forEach(item => {
if (! this.defaultCheckedKeys.find(_m => _m == item)) {
this.getNode(item).indeterminate = true
}
})
}
})
}
发现问题解决了,但是后来又发现了一个问题!!!
当父节点底下有几万个子节点时,发现不生效了,原因是啥呢重置子节点状态的方法(setChildNodeChecked )时,异步加载子节点不知道多长时间,而且就算把时间放长,等待到怀疑人生你的父节点的状态才有勾选变为半选
于是我在el-tree的node.js中找到doCreateChildren方法,当子节点大于2000条时设置checkStrictly等于true(父子节点不强制关联,当然父节点的选中状态是我手动判断),当数据加载完时将checkStrictly设置成false
当数据少于2000条时,上面的重置的方法够用我就没改了,就直接将checkStrictly设置成false
doCreateChildren方法是我进行处理过的,当一个节点的子节点数据大于2000条时,异步处理:https://blog.csdn.net/monparadis/article/details/114025100
doCreateChildren(array, defaultProps = {}) {
const store = this.store
if (array && array.length > 2000) {
let arr = [...array]
let num = 0
store.checkStrictly = true
let handler = setInterval (() => {
for (let i = 0; i < 500; i++) {
if (num < arr.length) {
this.insertChild(objectAssign({ data: arr[num] }, defaultProps), undefined, true)
num ++
}
if (num === arr.length) {
clearInterval(handler)
store.checkStrictly = false
}
}
})
} else {
store.checkStrictly = false
array.forEach((item) => {
this.insertChild(objectAssign({ data: item }, defaultProps), undefined, true)
})
}
}
当然这还有个问题当你树节点取消勾选进行操作时,记得把checkStrictly设置成false
到这里问题就解决了。