React之Ant Design基本框架搭建

最近項目需要使用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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章