vue3 antd Tree控件异步数据加载,对树增删改更新整个树的数据时,会导致节点的展开按钮消失,节点再也无法展开
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
1. 问题重现
相关代码:
---------------------- html部分
<template>
<a-tree :tree-data="treeData" :load-data="onLoadData" @select="select">
<template #title="{ key: treeKey, title, dataRef }">
<a-dropdown :trigger="['contextmenu']">
<span>{{ title }}</span>
<template #overlay>
<a-menu @click="({ key: menuKey }) => onContextMenuClick(treeKey, menuKey)">
<a-menu-item key="1" @click="nodeChildAdd(dataRef)">添加</a-menu-item>
<a-menu-item key="2" @click="nodeDelete(dataRef)">删除</a-menu-item>
<a-menu-item key="3">取消</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
</a-tree>
</template>
----------------------- ts部分
<script lang="ts">
export default defineComponent({
setup() {
const treeData = ref<TreeProps['treeData']>([])
const onContextMenuClick = (treeKey: string, menuKey: string | number) => {
console.log(`treeKey: ${treeKey}, menuKey: ${menuKey}`);
};
const expandedKeys = ref<string[]>([]);
const selectedKeys = ref<string[]>([]);
const loadedKeys=ref<string[]>([]);//已经加载的节点会存在这个里面
.....
// 加载一级节点
function getOneNode() {
let treeFather = [] as any
loadedKeys.value=[]
get(url,{}).then(res => {
if (res.length) {
res.map(el => {
treeFather.push({id: el.id, key: el.id, title: el.name})
})
}
treeData.value = treeFather
})
}
// 异步加载子节点
const onLoadData: TreeProps['loadData'] = (treeNode: any) => {
const treeChildren: any = []
get(url.getFaultType, {id: treeNode.id}).then(res => {
if (res.length) {
res.map(el => {
treeChildren.push({
id: el.end.id,
parentId: el.start.id,
key: el.end.id,
title: el.end.name,
})
})
}
})
return new Promise(resolve => {
if (treeNode.dataRef.children) {
resolve();
return;
}
setTimeout(() => {
treeNode.dataRef.children = treeChildren
treeData.value = [...treeData.value];
resolve();
}, 200);
});
}
.....
return {
treeData,
onContextMenuClick,
expandedKeys,
nodeChildAdd,
select, onLoadData, nodeDelete, updataClick,
};
},
})
</script>
展示:
原本为多层树形结构,选择某级进行编辑或者添加后重新调用getOneNode()函数进行刷新,一级节点展开按钮消失,再点也无反应
2.解决问题
tree提供的loadData属性,可添加loadedKeys属性,这样可将加载的节点装入其中,在编辑或添加等操作之后也不会出现节点消失的情况
如:
---------------------- html部分
<template>
<a-tree :tree-data="treeData" :load-data="onLoadData" @select="select"
:loadedKeys="loadedKeys">
....
</a-tree>
</template>
----------------------- ts部分
<script lang="ts">
export default defineComponent({
setup() {
const loadedKeys=ref<string[]>([]);//已经加载的节点会存在这个里面
....
return {
...,
loadedKeys
};
},
})
</script>
3.另一个问题
由于只是绑定loadedKeys,但是一直为[],点击叶子节点时会导致onLoad方法一直调用,从而进入死循环
界面截图:
解决方法:
---------------------- html部分
<template>
<a-tree :tree-data="treeData" :load-data="onLoadData" @select="select"
:loadedKeys="loadedKeys">
....
</a-tree>
</template>
----------------------- ts部分
<script lang="ts">
export default defineComponent({
setup() {
const loadedKeys=ref<string[]>([]);//已经加载的节点会存在这个里面
....
// 点击异步加载子节点
const onLoadData: TreeProps['loadData'] = (treeNode: any) => {
loadedKeys.value = [...loadedKeys.value, treeNode.key] //这里是antd-vue的获取key方式
.....
}
.....
return {
...,
loadedKeys
};
},
})
</script>
-------------------------------------------------------------------------------------------20240321
添加的时候发现一个问题:(不知道有没有一样的小伙伴)
当节点没有打开的时候,添加下一级完成后点击打开,这时候可以看到刚才添加的节点;
但是!如果已经打开了这个节点(也就是这个节点加载完成后打开)而且目前是叶子节点,则再添加节点不会再显示;
解决了两天,终于有一个简单的方法就是....在添加完成之后置空树,再调用加载一级节点的方法即可。
原来:
修改完:
代码:
// 添加 提交
function handleOk() {
get(url, {要传的参数}).then(res => {
treeData.value = []; //这里将树的数据置空
getOneNode() // 再次调用加载一级树的方法,奖会自动加载之前打开的节点(loadedKeys)
visible.value = false //添加窗口关闭
})
}
完成ψ(`∇´)ψ
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)