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

如何实现带垂直标签、点击垂直展开内容的React侧边栏菜单

React 垂直标签侧边栏菜单实现方案

核心实现思路

  • 定义两个状态变量:activeTab 存储当前激活的标签ID,isExpanded 标记侧边栏是否处于展开状态
  • 收拢状态下仅展示60px宽度的垂直标签栏,用CSS实现文字垂直排列
  • 点击标签时做判断:如果点击的是当前已激活标签则收起侧边栏,点击其他标签则切换激活项并保持展开状态
  • 切换标签时内容区直接更新对应内容,不需要重复触发收起展开动画

完整代码示例

组件逻辑代码

import { useState } from 'react'
import './VerticalSidebar.css'

// 菜单配置,可根据需求自行扩展
const menuItems = [
  {
    id: 'dashboard',
    label: '首页',
    icon: '🏠',
    content: [<p>数据概览</p>, <p>今日统计</p>, <p>待办事项</p>]
  },
  {
    id: 'user',
    label: '用户管理',
    icon: '👤',
    content: [<p>用户列表</p>, <p>权限配置</p>, <p>用户分组</p>]
  },
  {
    id: 'order',
    label: '订单管理',
    icon: '📦',
    content: [<p>全部订单</p>, <p>待发货订单</p>, <p>退款申请</p>]
  },
  {
    id: 'setting',
    label: '系统设置',
    icon: '⚙️',
    content: [<p>基础配置</p>, <p>日志查看</p>, <p>版本更新</p>]
  }
]

export default function VerticalSidebar() {
  const [activeTab, setActiveTab] = useState(null)
  const [isExpanded, setIsExpanded] = useState(false)

  // 标签点击事件
  const handleTabClick = (tabId) => {
    if (activeTab === tabId) {
      // 点击当前激活标签则收起侧边栏
      setIsExpanded(false)
      setActiveTab(null)
    } else {
      setActiveTab(tabId)
      setIsExpanded(true)
    }
  }

  return (
    <div className="sidebar-container">
      {/* 垂直标签栏 */}
      <div className="tab-bar">
        {menuItems.map(item => (
          <div 
            key={item.id}
            className={`tab-item ${activeTab === item.id ? 'active' : ''}`}
            onClick={() => handleTabClick(item.id)}
          >
            <span className="tab-icon">{item.icon}</span>
            <span className="tab-label">{item.label}</span>
          </div>
        ))}
      </div>

      {/* 展开内容区 */}
      {isExpanded && activeTab && (
        <div className="content-area">
          <h4>{menuItems.find(i => i.id === activeTab).label}</h4>
          <div className="content-body">
            {menuItems.find(i => i.id === activeTab).content}
          </div>
        </div>
      )}
    </div>
  )
}

配套样式代码(VerticalSidebar.css)

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.sidebar-container {
  display: flex;
  height: 100vh;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 999;
}

/* 垂直标签栏样式 */
.tab-bar {
  width: 60px;
  background: #2d3436;
  display: flex;
  flex-direction: column;
}

.tab-item {
  padding: 24px 0;
  color: #fff;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: background 0.2s ease;
}

.tab-item:hover, .tab-item.active {
  background: #636e72;
}

.tab-icon {
  font-size: 20px;
}

.tab-label {
  /* 实现文字垂直排列 */
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-size: 12px;
}

/* 展开内容区样式 */
.content-area {
  width: 240px;
  background: #fff;
  border-right: 1px solid #eee;
  padding: 16px;
  animation: slideIn 0.3s ease forwards;
}

@keyframes slideIn {
  from {
    transform: translateX(-10%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.content-body {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

功能说明

  • 初始状态侧边栏仅展示60px宽的垂直标签栏,符合收拢状态需求
  • 点击任意标签后右侧弹出内容区,展示对应标签的子内容
  • 点击当前已激活的标签时,内容区收起,回到仅展示标签的状态
  • 切换不同标签时,内容区直接更新为对应标签的内容,无多余交互
  • 所有样式均可根据实际设计需求调整宽度、颜色、动画效果等参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:36:02