You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中递归实现菜单及多级子菜单的动态渲染?

递归渲染多层导航菜单的实现方案

这问题我之前做后台管理系统的时候经常碰到,多层嵌套的菜单用递归处理是最优雅的方式,核心思路就是判断每个菜单项是否包含子菜单,有就递归调用渲染函数/组件。下面我给你两种常见场景的实现示例,你可以按需选用:

一、原生JavaScript(纯DOM操作)

如果你的项目没有用框架,直接用原生JS就能搞定。我们可以写一个递归函数,负责把菜单数据转换成DOM元素:

// 递归渲染菜单的函数
function renderMenuItems(menuItems, parentElement) {
  menuItems.forEach(item => {
    // 创建菜单项容器
    const menuItem = document.createElement('li');
    menuItem.classList.add('menu-item');

    // 创建菜单项标题
    const title = document.createElement('a');
    title.textContent = item.title;
    title.href = '#'; // 可以根据实际需求设置跳转链接
    menuItem.appendChild(title);

    // 如果有子菜单,递归渲染
    if (item.submenus && item.submenus.length > 0) {
      const subMenu = document.createElement('ul');
      subMenu.classList.add('submenu');
      // 递归调用,把子菜单数据和当前子菜单容器传进去
      renderMenuItems(item.submenus, subMenu);
      menuItem.appendChild(subMenu);
    }

    parentElement.appendChild(menuItem);
  });
}

// 初始化渲染
const menuContainer = document.getElementById('menu-container');
const menuData = [
  { title: "menu 1", submenus: [
    { title: "sub menu1" },
    { title: "sub menu2", submenus: [
      { title: "subsub menu1", submenus: [
        { title: "susubsub menu1" }
      ] },
      { title: "subsub menu2" }
    ] }
  ] },
  { title: "menu 2" }
];

renderMenuItems(menuData, menuContainer);

对应的基础CSS(可选,用来区分层级):

.menu-item {
  margin: 8px 0;
  list-style: none;
}
.submenu {
  margin-left: 20px;
  padding-left: 0;
}

二、React组件实现(更适合现代前端项目)

如果用React的话,递归组件会更简洁,我们可以拆分出Menu和MenuItem两个组件:

import React from 'react';

// 子菜单组件,递归调用自身
const Menu = ({ items }) => {
  if (!items || items.length === 0) return null;
  
  return (
    <ul className="menu-list">
      {items.map((item, index) => (
        <MenuItem key={index} item={item} />
      ))}
    </ul>
  );
};

// 单个菜单项组件
const MenuItem = ({ item }) => {
  return (
    <li className="menu-item">
      <a href="#" className="menu-title">{item.title}</a>
      {/* 如果有子菜单,递归渲染Menu组件 */}
      {item.submenus && <Menu items={item.submenus} />}
    </li>
  );
};

// 使用示例
const App = () => {
  const menuData = [
    { title: "menu 1", submenus: [
      { title: "sub menu1" },
      { title: "sub menu2", submenus: [
        { title: "subsub menu1", submenus: [
          { title: "susubsub menu1" }
        ] },
        { title: "subsub menu2" }
      ] }
    ] },
    { title: "menu 2" }
  ];
  
  return <Menu items={menuData} />;
};

export default App;

关键说明

  • 递归的终止条件:当菜单项没有submenus或者submenus为空数组时,就不会继续递归,只会渲染当前菜单项的标题。
  • 如果需要添加展开/收起功能,可以给MenuItem加一个状态(比如isExpanded),点击标题时切换状态,控制子菜单的显示隐藏(用CSS的display: none或者React的条件渲染)。
  • 实际项目中,建议给每个菜单项加唯一的key(不要用index,最好用后端返回的id),避免React渲染警告。

内容的提问来源于stack exchange,提问作者Devmasta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:04:59