在vue中封装构造树形结构方法,选中树形结构复选框,获取选中的id及半选中的id

博客围绕给用户分配菜单权限的需求展开。需将后端返回的扁平化数组转化为树形结构,先在utils的tree.js文件中封装构造树形结构的方法,可全局挂载。再通过el-tree组件实现页面UI树形效果,勾选复选框能获取选中及半选中的所有id。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:

需要给用户分配菜单权限,源菜单是扁平化数组,需要将数组转化为树形结构,选中节点复选框,获取该节点的id及半选中的id

首先,封装树形结构方法

我们可以在utils中新建一个tree.js的文件,在该文件中封装一个构造树形结构的方法
例如:

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export function handleTree(data, id, parentId, children) {
  let config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children'
  };

  var childrenListMap = {};
  var nodeIds = {};
  var tree = [];

  for (let d of data) {
    let parentId = d[config.parentId];
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
  }

  for (let d of data) {
    let parentId = d[config.parentId];
    if (nodeIds[parentId] == null) {
      tree.push(d);
    }
  }

  for (let t of tree) {
    adaptToChildrenList(t);
  }

  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
    }
    if (o[config.childrenList]) {
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c);
      }
    }
  }
  return tree;
}

使用方法:可以将此方法全局挂载

import { handleTree } from "@/utils/tree";
//全局方法挂载
Vue.prototype.handleTree = handleTree
//此时我们就可以通过this.handleTree的方法将扁平化数组构造成二维数组了
//假设menuList是从后端获取到的扁平化数组
 this.menuList = JSON.parse(
          JSON.stringify(res.data.menus).replace(/menuName/g, "label")
        );//此方法是为了将menuName通过正则的方式,改变属性名为label,这样是为了转为树形结构的时候,节点展示的内容为menuName
this.menuList = this.handleTree(this.menuList, "menuId");//将menuList造成树形结构数据

此时打印menuList就是转换为树形结构数据了
在这里插入图片描述

然后通过el-tree组件实现页面UI效果

    <el-tree
          :data="menuList"
          show-checkbox
          node-key="menuId"
          :props="defaultProps"
          :default-expand-all="false"
          ref="dept"
          class="tree-border"
          accordion
        >
//参数说明如下图
 defaultProps: {
        children: "children",
        label: "label",
      },

在这里插入图片描述

当我们勾选源菜单的内容时,页面都会有添加到目标菜单按钮,此时这个按钮需要触发一个事件

    // 所有部门节点数据
    getDeptAllCheckedKeys() {
      // 目前被选中的部门节点
      let checkedKeys = this.$refs.dept.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      console.log("checkedKeys", checkedKeys);
      return checkedKeys;
    },
    //源表格添加到右侧表格
    pushRight() {
      this.$confirm("是否给该用户配置勾选的菜单?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          //勾选中及半选中的所有菜单节点的id数组,此时就可以把这个传给后端了
          this.form.menuIds = this.getDeptAllCheckedKeys();
          addTenantMenu({
            menuIds: this.form.menuIds,
          }).then(() => {
            this.$message({
              showClose: true,
              message: "恭喜您,配置菜单成功!",
              type: "success",
            });
            this.chooseChange(this.platformId);//重新发起get请求,获取改动后的内容
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "配置取消!",
          });
        });
    },

到这里,我们就完成了将后端返回的扁平化数组转化为树形结构,并且通过el-tree组件来实现页面的UI树形效果,并且节点带有复选框,勾选复选框时获取勾选中及半选中的所有id

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cc980302

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值