最近项目需要使用react开发后台,边带着任务边学习了react,并结合ant design开发完成了任务。
本次博文主要记录的是从头开始开发一个后台,后台最基础的框架该是如何完成,并且切换菜单更改背景颜色作为active如何实现
BaseLayout.js
// BaseLayout.js
import React from 'react'
import {
HashRouter as Router, Route } from 'react-router-dom'
import {
Layout } from 'antd'
import PropTypes from 'prop-types'
import Sider from '../components/Sider'
import Header from '../components/Header'
import LogReport from '../../page/containers/LogReport'
import LogSend from '../../page/containers/LogSend'
import './BaseLayout.scss'
export default class BaseLayout extends React.PureComponent {
static propTypes = {
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
}
render() {
const {
location, history } = this.props
return (
<Router>
<Layout style={
{
height: '100%' }}>
<Header />
<Layout>
<Sider location={
location} history={
history} />
<Layout.Content styleName='layout-box'>
<Route path='/log-report' component={
() => <LogReport />} />
<Route path='/log-send' component={
() => <LogSend />} />
<Route path='/' exact component={
() => <LogReport />} />
</Layout.Content>
</Layout>
</Layout>
</Router>
)
}
}
components/Header.js
import React, {
PureComponent } from 'react'
import PropTypes from 'prop-types'
import {
Layout } from 'antd'
import './Header.scss'
export default class HeaderContainer extends PureComponent {
static contextTypes = {
router: PropTypes.object.isRequired,
}
render() {
return (
<Layout.Header styleName='container'>
<div styleName='logo'>
xxx后台管理系统
</div>
</Layout.Header>
)
}
}
components/Header.scss
.container {
background: #fff;
box-shadow: 0 2px 8px #f0f1f2;
height: 50px;
line-height: 50px;
z-index: 10;
}
.logo {
width: 150px;
line-height: 50px;
font-size: 16px;
text-align: center;
color: #333;
border-radius: 20px;
font-weight: 500;
}
.welcome {
color: #fff;
}
.menu{
line-height: 64px;
width: 300px;
}
components/Sider.js
import React, {
PureComponent } from 'react'
import PropTypes from 'prop-types'
import {
connect } from 'react-redux'
import {
Layout, Menu } from 'antd'
import {
Link } from 'react-router-dom'
import * as actions from '../reducer'
import './Sider.scss'
@connect(
state => ({
menus: state.app.menus,
}), actions)
export default class SiderContainer extends PureComponent {
static propTypes = {
menus: PropTypes.array,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
}
state = {
selectedKeys: [this.props.location.pathname],
}
componentDidMount() {
// 路由变化重新设置展开subMenu 重新设置选中key
this.props.history.listen(route => {
this.setState({
selectedKeys: [this.props.location.pathname] })
})
}
onSelectMenu = item => this.setState({
selectedKeys: item.selectedKeys })
render() {
const {
menus } = this.props
const {
selectedKeys } = this.state
return (
<Layout.Sider theme='light' width={
250} styleName='sider'>
<Menu
mode='inline'
selectedKeys={
selectedKeys}
onSelect={
this.onSelectMenu}
styleName='menu'>
{
!menus.length
? <Menu.Item disabled>尚未配置菜单</Menu.Item>
: menus.map(menu =>
<Menu.Item key={
`${
menu.url}`}>
<Link to={
menu.url} replace>{
menu.label}</Link>
</Menu.Item>
)
}
</Menu>
</Layout.Sider>
)
}
}
components/Sider.css
.sider {
border-right: 1px solid #eee;
overflow: auto;
display: flex;
width: 216px;
box-sizing: border-box;
flex-shrink: 0;
flex-direction: column;
border-right: 1px solid #e5e5e5;
background: #fff;
}
.tabs-bar {
:global(.ant-tabs-bar) {
margin-bottom: 0;
}
:global(.ant-tabs-nav) {
display: block;
> div {
display: flex;
}
:global(.ant-tabs-tab-active) {
color: #001529;
}
}
:global(.ant-tabs-tab) {
flex: 1;
text-align: center;
margin: 0 !important;
padding-left: 0;
padding-right: 0;
}
:global(.ant-tabs-ink-bar) {
background-color: #001529;
}
:global(.ant-menu-item),
:global(.ant-menu-submenu-title) {
padding-left: 16px !important;
}
:global(.ant-menu-item-selected) {
background-color: #f2f2f2 !important;
}
}
.menu:global(.ant-menu) {
border-right: 0;
}
.loading:global(.anticon) {
display: block;
margin: 0 auto;
}