vben admin BasicTree菜单分配子项不必全部选中时,父级也传给后端

vben admin BasicTree菜单分配子项不必全部选中时,父级也传给后端

同一个界面内:

 <BasicTree
          v-model:value="model[field]"
          :treeData="treeData"
          :fieldNames="{ title: 'resourceName', key: 'id' }"
          checkable
          toolbar
          search
          title="菜单分配"
          :draggable="true"
          :selectable="false"
        />
      </template>
    </BasicForm>

​ 获取到后端返回数据展示:

const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    resetFields();
    setDrawerProps({ confirmLoading: false });
    // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
    if (unref(treeData).length === 0) {
      let res = await getResourceTreeInfoApi();
      treeData.value = res.data as any as TreeItem[];
    }
    isUpdate.value = !!data?.isUpdate;

    if (unref(isUpdate)) {
      // 过滤掉data.record.resourceIds的父节点
      let res = cloneDeep(data.record.resourceIds);
      data.record.resourceIds = filterLeafNodeIds(treeData.value, res);

      rowId.value = data.record.id;
      setFieldsValue({
        ...data.record,
      });
    }
  });
  
   // 挂载时过滤掉目录父节点---------
  function filterLeafNodeIds(tree, arr2) {
    const result = new Set();

    // 辅助函数,用于确定节点是否为叶子节点
    function isLeafNode(node) {
      return node.children.length === 0;
    }

    // 递归函数,用于遍历树并筛选出叶子节点的id
    function traverse(node) {
      if (arr2.includes(node.id) && isLeafNode(node)) {
        result.add(node.id);
      } else if (node.children) {
        node.children.forEach((child) => traverse(child));
      }
    }

    // 从树的根节点开始递归
    tree.forEach((root) => traverse(root));

    // 将 Set 转换为数组并返回
    return Array.from(result);
  }

前端添加或修改数据时加入父节点

  async function handleSubmit() {
    try {
      const values = await validate();
      setDrawerProps({ confirmLoading: true });

      // 对data2中的每个id执行操作,如果id是父节点,则直接返回,不再添加---
      let ids = cloneDeep(values.resourceIds);
      ids.forEach((id) => {
        addParentIdsIfNotPresent(id, treeData.value, ids);
      });
      // data2现在包含了所有id及其所有不在data2中的父节点的id---

      if (isUpdate.value) {
        values.id = rowId.value;
        await updateRoleApi({ ...values, resourceIds: ids });
      } else {
        await addRoleApi({ ...values, resourceIds: ids });
      }
      // TODO custom api
      closeDrawer();
      emit('success');
    } finally {
      setDrawerProps({ confirmLoading: false });
    }
  }

// 提交时查找当前节点------
  function addParentIdsIfNotPresent(nodeId, data1, data2) {
    // 查找当前节点
    const node = findNodeById(data1, nodeId);
    // 如果当前节点存在且其parentId不是null且不在data2中
    if (node && node.parentId !== null && !data2.includes(node.parentId)) {
      // 将父节点id添加到data2中
      data2.push(node.parentId);
      // 递归地添加当前节点的父节点id
      addParentIdsIfNotPresent(node.parentId, data1, data2);
    }
  }
  function findNodeById(data, id) {
    // 辅助函数,用于根据 id 查找节点
    for (const node of data) {
      if (node.id === id) return node;
      if (node.children) {
        const found = findNodeById(node.children, id);
        if (found) return found;
      }
    }
    return null;
  }
  //-------
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值