有关若依菜单管理的改造

导言:

搞了个后端对接若依前端,对接菜单管理时候懵懵的就搞完了,也是搞了很久。记一下逻辑和要注意的东西,以后做想似的能有个改造思路。

逻辑:

主要是要把后端传过的数组列表做成类似

这样的,所以要转格式

后端传过来的数据:

复制代码
const data = [
  { id: 1, name: '根节点1', parentId: null },
  { id: 2, name: '根节点2', parentId: null },
  { id: 3, name: '子节点1-1', parentId: 1 },
  { id: 4, name: '子节点1-2', parentId: 1 },
  { id: 5, name: '子节点2-1', parentId: 2 },
  { id: 6, name: '子节点1-1-1', parentId: 3 },
  { id: 7, name: '子节点1-1-2', parentId: 3 }
];

转换成el-table要的

复制代码
const tree = [
  {
    id: 1,
    name: '根节点1',
    parentId: null,
    children: [
      {
        id: 3,
        name: '子节点1-1',
        parentId: 1,
        children: [
          { id: 6, name: '子节点1-1-1', parentId: 3 },
          { id: 7, name: '子节点1-1-2', parentId: 3 }
        ]
      },
      { id: 4, name: '子节点1-2', parentId: 1 }
    ]
  },
  {
    id: 2,
    name: '根节点2',
    parentId: null,
    children: [
      { id: 5, name: '子节点2-1', parentId: 2 }
    ]
  }
];

若依是定义了一个方法来实现转换的过程,大致思路:

  • 第一次循环用于建立节点之间的父子关系映射。
  • 第二次循环用于识别根节点并初始化树的结构。
  • 第三次循环则利用递归构建完整的树形结构,确保所有节点的层级关系正确。

讲实话我还是懵懵的,模糊理解

1.把扁平数组每个数据看成点,两点之间连线

2.分别把两点连线是父节点的一端找到

3.对应接起来

没什么实感..

实现

1.index.vue

请求后端,获得数据,调用handleTree转换格式,绑到表格上

复制代码
/** 查询菜单列表 */
    getList() {
      this.loading = true;
      listMenu(this.queryParams).then(response => {
        console.log("请求信息response:",response);
        
        this.menuList = this.handleTree(response.data, "id","parentUID");
        console.log("请求信息this.menuList:",this.menuList);
        this.loading = false;
      });
    },

2.handleTree()转换

在src\utils\ruoyi.js里.

把扁平化的数组数据结构(通常是包含父子关系的节点)转换为一个树形结构

复制代码
/**
 * 构造树型结构数据
 * @param {*} data 数据源           // 输入的原始数据,是一个扁平结构的数组
 * @param {*} id id字段 默认 'id'   // 数据中表示唯一标识符的字段名,默认为 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'  // 数据中表示父节点的字段名,默认为 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'  // 用来存储子节点的字段名,默认为 'children'
 */
export function handleTree(data, id = 'id', parentId = 'parentId', children = 'children') {
  
  // 配置对象,定义了 id 字段、parentId 字段、children 字段的名称
  let config = {
    id: id || 'id',                      // id 标识字段,默认为 'id'  
    parentId: parentId || 'parentId',     // 父节点标识字段,默认为 'parentId'
    childrenList: children || 'children'  // 子节点列表字段,默认为 'children'
  };

  // 存储每个父节点对应的子节点数组
  var childrenListMap = {}; 
  
  // 存储所有节点的 id 及其节点对象,用于快速查找
  var nodeIds = {};  
  
  // 最终的树形结构数组,存储根节点
  var tree = [];

  // 第一次循环:构建 childrenListMap 和 nodeIds
  for (let d of data) {
    let parentId = d[config.parentId];    // 获取当前节点的父节点 id

    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];     // 如果该父节点还没有子节点数组,则初始化
    }
    
    nodeIds[d[config.id]] = d;            // 保存当前节点的 id 和节点本身,方便快速查找
    childrenListMap[parentId].push(d);     // 将当前节点加入到其父节点对应的子节点数组中

  }

  
  // 第二次循环:找出根节点,并添加到 tree 数组中
  for (let d of data) {
    let parentId = d[config.parentId];     // 获取当前节点的父节点 id

    if (nodeIds[parentId] == null ) {       // 如果当前节点的父节点不存在,说明它是根节点
      tree.push(d);                        // 将根节点加入到树结构中

    }
  }
  // 第三次循环:递归遍历根节点的子节点,并构造完整的树形结构
  for (let t of tree) {
    
    adaptToChildrenList(t);                // 递归处理每个根节点,生成其子节点结构
  }

  /**
   * 递归地将子节点添加到对应的父节点中
   * @param {*} o 当前正在处理的节点对象
   */
  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];   // 将子节点数组添加到当前节点的 children 字段
    }
   
    if (o[config.childrenList]) {                               // 如果当前节点有子节点
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c);                                 // 递归处理每个子节点
      }
    }
  }

  // 返回最终构造好的树形结构
  return tree;
}

注意的点

1.handleTree()

这方法开始定义了config对象,其中把每个字段的父节点id,子节点的名字都规范好了,如果后端这俩传来的不一样的话在调用handleTree()时对应传过去就行,不然不一样用了默认的话会报错。

2.后端数据

后端传过来的每条数据都应该带上parentId字段,不管有没有,不然也会报错

3.el-table绑定

绑定的是本身的id,不是父节点的,绑父节点的会报键重复

javascript 复制代码
<el-table
      v-if="refreshTable"
      v-loading="loading"
      :data="menuList"
      row-key="id"
      :default-expand-all="isExpandAll"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
    >
相关推荐
阿阳微客5 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
狼性书生10 小时前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件
Chef_Chen10 小时前
从0开始学习R语言--Day18--分类变量关联性检验
学习
键盘敲没电10 小时前
【IOS】GCD学习
学习·ios·objective-c·xcode
海的诗篇_11 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试
AgilityBaby11 小时前
UE5 2D角色PaperZD插件动画状态机学习笔记
笔记·学习·ue5
AgilityBaby11 小时前
UE5 创建2D角色帧动画学习笔记
笔记·学习·ue5
武昌库里写JAVA12 小时前
iview Switch Tabs TabPane 使用提示Maximum call stack size exceeded堆栈溢出
java·开发语言·spring boot·学习·课程设计
一弓虽13 小时前
git 学习
git·学习
Moonnnn.15 小时前
【单片机期末】串行口循环缓冲区发送
笔记·单片机·嵌入式硬件·学习