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 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐