多个树型 同步数据问题踩坑
先放效果图
左侧是 leftdata 右侧是rightdata 这是俩个不同接口下的数据,并且俩个树形都是使用懒加载的模式.
–
踩坑1
使用getCheckedNodes拿到的数据 是所有勾选过的数据
不论数据是一级还是二级三级 都会放在同一个数组中
this.$refs.XXXX.getCheckedNodes()
踩坑2
懒加载模式的情况下 单纯的修改 children 数据是不会让页面更新出数据的
需要手动刷新并且更新数据,代码如下
// >>按键触发 我这里的 treeSelectedDataValue 是父节点 也就是图中的数值1
// 我是根据getCheckedNodes来获取右侧是否有相同的大节点的 如果有那就进行刷新 并且更新数据
// 没有的话直接push大数组即可
---------------
// 没有重复的直接赋值 上面代码部分省略 这里就是循环了一下右侧的数据查找有没有一样的然后进行别的操作
if (_index === -1) {
// 没有一样的给右边的数据赋值(请注意 懒加载这里直接赋值也是不行的,展开会没有数据)
this.treeSelectedData.push(data)
} else {
const treeSelectedDataValue = this.treeSelectedData[_index]
treeSelectedDataValue.childSysOrganizeIdList = []
data.childSysOrganizeIdList && data.childSysOrganizeIdList.forEach((res) => {
treeSelectedDataValue.childSysOrganizeIdList.push(res)
})
const node = this.$refs.faceRight.getNode(treeSelectedDataValue) // 根据 data找到node节点
node.loaded = false
node.expand() // 让节点进行刷新 这里会触发 loadNodeRight
// 这里的 loadNodeRight 是树形结构设置的更新触发的函数(重点) 也就是 :load="XXXXXXX"
// 请注意 load需要设置 懒加载模式才会触发 也就是 下面的 lazy
<el-tree
ref="faceRight"
class="content-el-tree"
:data="treeSelectedData"
:props="defaultProps"
:load="loadNodeRight"
draggable
node-key="sysOrgId"
lazy
@node-drop="nodeDragStart"
>
// resolve会重新处理树形node的结构 下面的进行了循环push 然后重新设置了node 使得页面可以显示出数据
// 另外 请注意 loadNodeRight触发的是当前节点下的 node实际指向的是一个节点(而非整个数组)
// 具体还是直接打印node 比较直观 这里不多说
async loadNodeRight(node, resolve, organizeId) {
let data = []
if (node.data) {
resolve(data) //如果没走下面的if那肯定是需要返回一个data的
// 这里其实拖拽也用到了更新数据 原理跟上面的差不多 只不过没有那么麻烦 需要手动触发刷新
// 如果是拖拽且没有重复数据那就需要触发加载 并且把拖拽的内容添加进去 node.expand()触发的会走这个
if (node.data.childSysOrganizeIdList) {
const key = node.childNodes.map(item => item.key)
node.data.childSysOrganizeIdList.forEach((res, index) => {
if (key.indexOf(node.data.childSysOrganizeIdList[index].sysOrgId) === -1) {
data.push(node.data.childSysOrganizeIdList[index])
}
})
// 相当于把里面的data都返回去了 会生成node节点让数据保持一致(重要)
// 另外贴出的代码只有部分 不能直接进行复制,请理解原理然后加以使用
// 文章有错误也可以指出!
resolve(data)
}
}
},
}
三 一键展开某个节点数据
因为懒加载的情况 所有数据都需要点开后才会显示 一个个点开比较浪费时间,所以出现了一键展开的需求,如图
贴出部分代码 如下,可以看着理解
主要两个参数
node-key 和 :default-expanded-keys
node-key 为展开的节点id default-expanded-keys为定义参数 push进去id即会触发调用数据
<el-tree
ref="treeLeft"
class="content-el-tree"
:data="treeData"
:show-checkbox="true"
:default-expanded-keys="expandedKeys"
node-key="sysOrgId"
lazy
:load="loadNode"
:props="defaultProps"
@check-change="checkChange"
>
<span class="custom-tree-node" slot-scope="{ node, data }" >
<span>{{ node.label }}</span>
<span class="active2">
<el-button
type="text"
@click.stop="() => doSpread({node, data})"
>一键展开</el-button>
</span>
</span>
</el-tree>
//这一段代码还可以优化 不要一模一样抄
// 一键展开当前表的数据(延迟不要低于500 不然会有概率少展开部分数据... 网络延迟的情况)
// 这一块写的不是很好 能不用定时器还是不用定时器,但是目前没有什么好的解决方案
async doSpread({ node, data }) {
await this.$myConfirm('确定要展开本部门下的所有数据么', this)
this.expandedKeys = []
this.expandedKeys.push(node.data.sysOrgId)
spread(node, this)
function spread(val, than) {
setTimeout(() => {
const childNodes = val.childNodes
for (let i = 0; i < childNodes.length; i++) {
than.expandedKeys.push(childNodes[i].data.sysOrgId) // 循环data的数据,把对应要展开的节点id放入展开的数组中
setTimeout(() => { if (childNodes[i].childNodes.length > 0) { spread(childNodes[i], than) } }, 1000)
}
}, 1000)
}
},
// 第一次写文章,还有很多不足,如有错误可以指出。