Tencent / tdesign-vue

A Vue.js UI components lib for TDesign.
https://tdesign.tencent.com/vue
MIT License
887 stars 339 forks source link

[t-tree] 树组件回显问题 #3132

Open lhdhtrc opened 2 months ago

lhdhtrc commented 2 months ago

这个功能解决了什么问题

解决回显解决携带父级id,导致半选变全选问题

你建议的方案是什么

// 辅助函数,用于递归检查节点的子节点是否都包含在selectedIds中
const areChildrenFullySelected = (node: any, selectedIds: string[]) => {
  if (!node.children || node.children.length === 0) {
    return true; // 如果没有子节点,则认为它是完全选中的
  }

  for (const child of node.children) {
    if (!selectedIds.includes(child.id)) {
      return false; // 如果任何一个子节点不在selectedIds中,则不是完全选中
    }
  }
  return true; // 所有子节点都完全选中
};

// 递归检查所有节点及其子节点,收集完全选中的ID
const collectFullySelectedIds = (nodes: any, selectedIds: string[]): any => {
  const fullySelectedIds = [];
  for (const node of nodes) {
    if (selectedIds.includes(node.id) && areChildrenFullySelected(node, selectedIds)) {
      fullySelectedIds.push(node.id);
    }
    if (node.children) {
      fullySelectedIds.push(...collectFullySelectedIds(node.children, selectedIds));
    }
  }
  return fullySelectedIds;
};

export const useTreeFilter = (tree: any[], selectedIds: string[]) => {
  // 从树的根节点开始收集完全选中的ID
  return collectFullySelectedIds(tree, selectedIds);
};

这只是一个简单的例子,方便后续的查找

github-actions[bot] commented 2 months ago

👋 @lhdhtrc,感谢给 TDesign 提出了 issue。 请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。

uyarn commented 2 months ago

回显解决携带父级id,导致半选变全选 是指什么时候额?

lhdhtrc commented 2 months ago

@uyarn 例如返回数据是[p1, c1, c2], p1下有c1, c2 c3,但是这里只返回了p1下的c1,c2, 那么如果回显到数组件上p1节点会变成全选,这个时候就需要去做处理,看p1下是否存在c1, c2, c3如果存在则不过滤p1, 如果存在则过滤p1

lhdhtrc commented 2 months ago
<template>
   <t-tree
    ref="menuRef"
    v-model="formData.menuIdList"
    class="narrow-scrollbar"
    max-height="300px"
    checkable
    value-mode="all"
    :expand-all="menuAll"
    :data="menu"
    :keys="{ value: 'id', label: 'name', children: 'children' }"
    @change="treeChange($event, 0)"
  ></t-tree>
</template>

<script>
......
const onWatcher = watch(
  () => props.active,
  async () => {
    if (props.active) {
      switch (props.type) {
        case 0:
          break;
        case 1:
          loading.value = true;
          try {
            const res = await GetRoleInfoAPI(props.row.id);
            res.menuIdList = useTreeFilter(props.menu, res.menuIdList);
            res.deptIdList = useTreeFilter(props.dept, res.deptIdList);
            formData.value = res;

            menuAll.value = res.menuIdList.length === menuRef.value.getItems().length;
            deptAll.value = res.deptIdList.length === deptRef.value.getItems().length;
          } catch (err) {
            console.log(err);
          }
          loading.value = false;
          break;
        default:
      }
    } else {
      formData.value = JSON.parse(JSON.stringify(reset));
    }
  },
);
......
</script>