前言
写了一个类似element ui的级联面板的那个组件,不同的是,组件可以类似tree选择,选择某个子元素,就返回单个子元素,选择所有子元素,返回父元素。回头整理一下。开源出来。
难点
感觉难点就是数据回填,数据操作倒是不是很难。
数据操作思路:
选中某个节点,然后根据其parent_id,递归查找父元素。假如子元素个数和选中个数相等,父元素选中,不相等,则所有父元素半选状态。
数据回填就稍微麻烦一点
首先:递归查找到要回填的数据,使其状态为选中,假如选中的数据有子元素,则所有子元素选中。
其次,找到选中数据的所有父元素,然后改变其状态,使其变为半选。然后对数据进行一个展示。
部分代码
递归查找所有父元素代码:
findAllParent(node, tree, parentNodes = [], index = 0) {
if (!node || !node[this.sprops.parent]) {
return
}
this.findParent(node, parentNodes, tree)
let parentNode = parentNodes[index]
this.findAllParent(parentNode, tree, parentNodes, ++index)
return parentNodes
},
findParent (node, parentNodes, tree) {
for (let i = 0; i < tree.length; i++) {
let item = tree[i]
if (item[this.sprops.value] === node[this.sprops.parent]) {
parentNodes.push(item)
return
}
if (item.children && item.children.length > 0) {
this.findParent(node, parentNodes, item.children)
}
}
},
递归查找当前节点源码
getCheckedNodes(data, value) {
data.forEach(item => {
if (value === item[this.sprops.value]) {
this.checkedNodes.push(item)
this.$set(item, 'checked', true)
this.$set(item, 'isIndeterminate', false)
this.childrenChecked(item, true)
} else {
if (item.children && item.children.length > 0) {
this.getCheckedNodes(item.children, value)
}
}
})
},
回填代码,对所有父元素进行半选。
valForeach(val) {
val.forEach(item => {
this.getCheckedNodes(this.options, item)
})
let checkednodeTree = {}
this.checkedNodes.forEach(node => {
checkednodeTree[node[this.sprops.value]] = this.findAllParent(node, this.options)
})
// console.log(checkednodeTree)
for (let key in checkednodeTree) {
if (checkednodeTree[key] && checkednodeTree[key].length > 0) {
let parentArray = checkednodeTree[key].reverse()
parentArray.forEach((item, index) => {
this.$set(item, 'isIndeterminate', true)
this.onelineClick(item, index + 1, 'init')
})
}
}
},
上述就是对于查找树结构,循环递归查找节点的一些介绍。