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

如何用ReactJS实现从右向左折叠的左侧侧边栏?

实现React左侧导航栏左右折叠(替代react-collapsible方案)

方案一:改造react-collapsible实现水平折叠

react-collapsible默认是基于height的垂直折叠,要改成水平方向,需要强制覆盖它的核心CSS样式,将高度过渡替换为宽度过渡:

修改后的JSX代码

import { useState } from 'react';
import { BsChevronLeft, BsChevronRight } from 'react-icons/bs';
import Collapsible from 'react-collapsible';

const [isOpen, setIsOpen] = useState(true);

// 根据折叠状态切换箭头方向
const customTrigger = (isCurrentOpen) => (
  <div className="Collapsible__trigger">
    {isCurrentOpen ? <BsChevronLeft /> : <BsChevronRight />}
  </div>
);

return (
  <div className="sidebar-wrapper">
    <Collapsible 
      trigger={customTrigger}
      onOpen={() => setIsOpen(true)}
      onClose={() => setIsOpen(false)}
    >
      <Sidebar />
    </Collapsible>
  </div>
);

覆盖组件默认CSS

/* 重置垂直折叠的核心样式,改为水平宽度过渡 */
.Collapsible__content-wrapper {
  height: auto !important;
  max-height: none !important;
  width: 250px; /* 导航栏展开宽度 */
  transition: width 0.3s ease-in-out !important;
  overflow: hidden;
}

.Collapsible__content-wrapper.is-closed {
  width: 0 !important;
  padding: 0 !important; /* 移除默认内边距,避免收起时留白 */
}

/* 调整触发按钮位置 */
.Collapsible__trigger {
  display: flex;
  align-items: center;
  font-size: 20px;
  color: rgb(187, 186, 186);
  padding: 10px;
  cursor: pointer;
  position: absolute;
  left: 250px; /* 展开时对应导航栏宽度 */
  top: 10px;
  background: #fff;
  z-index: 10;
}

/* 折叠时同步移动触发按钮 */
.is-closed ~ .Collapsible__trigger {
  left: 0;
}

.Collapsible__trigger svg {
  transition: transform 0.3s ease;
}

注意:这种方式依赖覆盖组件默认样式,若组件版本更新可能导致样式失效,仅作为临时兼容方案。


方案二:自定义实现(推荐)

直接用React状态+CSS过渡实现,完全自定义逻辑,无第三方组件依赖问题:

完整组件代码

import { useState } from 'react';
import { BsChevronLeft, BsChevronRight } from 'react-icons/bs';

const Dashboard = () => {
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);

  const toggleSidebar = () => {
    setIsSidebarOpen(!isSidebarOpen);
  };

  return (
    <div className="dashboard-container">
      {/* 左侧导航栏 */}
      <div className={`sidebar ${isSidebarOpen ? 'open' : 'closed'}`}>
        <div className="sidebar-content">
          <h3>导航菜单</h3>
          <ul>
            <li>首页</li>
            <li>数据分析</li>
            <li>系统设置</li>
          </ul>
        </div>
      </div>

      {/* 折叠触发按钮 */}
      <button className="sidebar-toggle" onClick={toggleSidebar}>
        {isSidebarOpen ? <BsChevronLeft /> : <BsChevronRight />}
      </button>

      {/* 主内容区 */}
      <div className="main-content">
        <h1>仪表盘主内容</h1>
        <p>导航栏折叠时,此区域会自动填充剩余空间</p>
      </div>
    </div>
  );
};

export default Dashboard;

对应的CSS样式

/* 全局容器用flex布局,实现导航栏与主内容并排 */
.dashboard-container {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* 导航栏基础样式 */
.sidebar {
  width: 250px;
  background-color: #f5f5f5;
  border-right: 1px solid #eee;
  transition: width 0.3s ease-in-out;
  overflow: hidden;
}

.sidebar.closed {
  width: 0;
}

.sidebar-content {
  padding: 20px;
}

/* 触发按钮样式 */
.sidebar-toggle {
  position: absolute;
  left: 250px;
  top: 10px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 8px;
  cursor: pointer;
  transition: left 0.3s ease-in-out;
  z-index: 100;
}

/* 折叠时调整按钮位置 */
.sidebar.closed ~ .sidebar-toggle {
  left: 10px;
}

/* 主内容区自动填充剩余空间 */
.main-content {
  flex: 1;
  padding: 20px;
}

这种方案的优势:

  • 完全自定义逻辑,不受第三方组件限制
  • 动画流畅,内容自适应逻辑清晰
  • 易扩展(比如添加收起时的图标导航、响应式适配)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:27:25