侧边导航栏

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { Link, IndexLink } from 'dva/router'
import { Icon, intl, Truncate } from '@ali/wind'
import './index.less'

const NavItem = ({ title }) => (
<div>
<span className="icon-wrap" title={title}><Icon type="arrow-down-filling" size="small" /></span>
<span className="nav-title"><Truncate type="width" value="120px">{title}</Truncate></span>
</div>
)
const MenuItem = ({ iconType, title }) => (
<div>
<span className="icon-wrap" title={title}><Icon type={iconType} size="small" /></span>
<span className="nav-title"><Truncate type="width" value="120px">{title}</Truncate></span>
</div>
)

const SecondMenuList = ({ itemData }) => {
const listDom = itemData.map((menuItem, index) => {
const { routerPath = '/', iconType, title } = menuItem
return (
<li key={index}>
<Link to={routerPath} activeClassName="active">
<MenuItem iconType={iconType} title={title} />
</Link>
</li>
)
})
return (
<div className="sidebar-second-wrap">
<ul className="sidebar-second-class">
{listDom}
</ul>
</div>

)
}

const FirstMenu = ({ menu, index, onClick, children }) => (
<div className={`sidebar-nav ${menu.activeState ? 'active' : ''}`}>
<div
className="sidebar-first-class"
onClick={(e) => onClick(index, e)}
>
{/* 一级目录 */}
{(menu.routerPath !== undefined) ? (<IndexLink to={menu.routerPath} activeClassName="active">
<NavItem title={menu.title} />
</IndexLink>) : <NavItem title={menu.title} />}
</div>
{/* 二级目录 它的显示和隐藏是通过active类名来决定的 有该active类名 其height:auto 没有该类名其height:0*/}
{children}
</div>
)
const MenuList = ({ menuDatas, className, onClick }) => {
const menuDOM = menuDatas.map((menu, index) => (
<FirstMenu menu={menu} key={index} index={index} onClick={onClick}>
{menu.children && menu.children.length && <SecondMenuList itemData={menu.children} />}
</FirstMenu>
))
return (
<div className={className}>
{menuDOM}
</div>
)
}
class SideBar extends Component {
constructor(){
super()
this.state={
menuDatas:[
{
title: intl('aso.net.change.merge.IntegrationImplementation', true),
activeState: true,
children: [
{ title: intl('aso.net.change.merge.PhysicalNetworkIntegration', true), routerPath: 'netChange/mergeNet' },
],
},

]
}

}
changeMenuState(menuIndex) {
let {menuDatas}=this.state
const newData = menuDatas.slice()
//点击切换文件的展开和收起
if (menuDatas[menuIndex].activeState === true) {
//如果之前是展开的 点击后收起
newData[menuIndex].activeState = false
} else {
//如果之前文件是收起来的 点击后展开 让其他的都收起
newData.forEach(menu => {
menu.activeState = false
})
newData[menuIndex].activeState = true
}
this.setState({ menuDatas: newData })
}
render() {
const menuClass = classnames({
sidebar: true,
})
return (
<div className={menuClass}>
<MenuList menuDatas={this.state.menuDatas} className="sidebar-wrap" onClick={(index) => this.changeMenuState(index)} />
</div>
)
}
}
export default SideBar

 

 

@sidebarBgColor: #0B0C0D;
@firstMenuBgColor:#0B0C0D;
@secondMenuBgColor:#1a1c1f;
@acitveBgColor: #00C1DE;
:global{
.sidebar {
float: left;
background-color: @sidebarBgColor;
z-index: 109;
width: 180px;
height: 100%;
transition: width 0.2s;
&.miniBar{
width: 50px;
overflow: hidden;
.nav-title{
opacity: 0;
}
}
.sidebar-wrap{
width: 180px;
}
.sidebar-menu {
text-align: center;
height: 30px;
line-height: 30px;
background-color: #1D2730;
cursor: pointer;

}
.sidebar-nav {
color: #D2D3D3;
.wind-truncate{
vertical-align: top
}
a{
display: block;
color: #D2D3D3;
text-decoration: none;
&.active{
background-color: @acitveBgColor;
color: #fff;
.next-icon{
color: #fff;
}
}
}
&.active{
.sidebar-first-class{
.next-icon{
transform: rotateZ(0) scale(.5);
}
}
.sidebar-second-class{
height: auto;
}
}
}
.sidebar-first-class {
height: 40px;
line-height: 40px;
color: #D2D3D3;
background-color: @firstMenuBgColor;
cursor: pointer;
.next-icon{
transform: rotateZ(-90deg) scale(.5);
}
&:hover{
background-color: @acitveBgColor;
.nav-title{
color: #fff;
}
.next-icon{
color: #fff;
}
}
.icon-wrap{
margin-left: 16px;
margin-right: 8px;
}
}
.sidebar-second-wrap{
max-height: 220px;
background-color: @secondMenuBgColor;
overflow: auto;
&::-webkit-scrollbar-thumb{
background-color: rgba(255,255,255,.8);

}
}
.sidebar-second-class {
height: 0;
overflow: hidden;
// background-color: @secondMenuBgColor;
.icon-wrap{
display: inline-block;
width: 50px;
text-align: center;
}
// .next-icon{
// color: #A3B9CC;
// }
li {
height: 40px;
line-height: 40px;
a {
display: block;
//color: #D2D3D3;
color:#00C1DE;
}
&:hover {
background-color: #222426;
a {
color: #fff;
}
// .next-icon{
// color: #fff;
// }
}
&.current {
background-color: #00C1DE;
a {
color: #fff;
}
.next-icon{
color: #fff;
}
}
}
}
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Bootstrap侧边导航可以使用Bootstrap提供的`nav`和`nav-pills`组件来实现。下面是一个简单的例子: ```html <div class="container-fluid"> <div class="row"> <nav class="col-md-2 d-none d-md-block bg-light sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column nav-pills"> <li class="nav-item"> <a class="nav-link active" href="#">菜单1</a> </li> <li class="nav-item"> <a class="nav-link" href="#">菜单2</a> </li> <li class="nav-item"> <a class="nav-link" href="#">菜单3</a> </li> </ul> </div> </nav> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center"> <h1 class="h2">标题</h1> </div> <div class="table-responsive"> <table class="table table-striped table-sm"> <thead> <tr> <th>表头1</th> <th>表头2</th> <th>表头3</th> <th>表头4</th> <th>表头5</th> </tr> </thead> <tbody> <tr> <td>内容1</td> <td>内容2</td> <td>内容3</td> <td>内容4</td> <td>内容5</td> </tr> </tbody> </table> </div> </main> </div> </div> ``` 这里使用了Bootstrap提供的`nav-pills`组件,添加了三个导航菜单项,并设置了第一个菜单项为激活状态。在`nav`标签中,`flex-column`类将菜单项垂直排列,`nav-link`类设置了导航链接的样式。在`col-md-2`类中,`d-none d-md-block`类将侧边在小屏幕上隐藏,只在中等屏幕以上显示。 在`main`标签中,`col-md-9`类设置了主内容区域的宽度,`ml-sm-auto`类将内容区域左对齐,`pt-3 px-4`类添加了一些顶部和左右的内边距,`table-responsive`类使表格具有响应式布局。 你可以根据自己的需求进行调整和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值