iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 22
0
Modern Web

30天React從入門到入坑系列 第 22

DAY22:React實作小專案(layout實作)

  • 分享至 

  • xImage
  •  

規劃Wireframe
https://ithelp.ithome.com.tw/upload/images/20180110/20107317mXe0vjxVSf.png

初步規劃Wireframe,大致分為3塊上面的header,左邊的sidebar和右邊的content。為了實作的簡單性,先把這3塊實作成layout component,當使用者點選左邊的sidebar再替換右邊的content內容。元件資料內容使用線上fake api,直接拿線上users當測試資料使用。

JSONPlaceholder
Fake Online REST API for Testing and Prototyping powered by JSON Server and lowdb
https://jsonplaceholder.typicode.com/

components

  • Layout(外框架)
  • Notices(公告內容)
  • UserInfo(sidebar item1)
  • PhoneInfo(sidebar item2)

實作layout component第一個碰到的問題,我們先從react-bootstrap來看看sidebar的UI範例。Nav UI主要是key值來切換NavItem再對到href,來達到頁面的切換。

Navs
https://react-bootstrap.github.io/components/navs/

react-bootstrap Nav
<Nav bsStyle="pills" activeKey={1} onSelect={handleSelect}>
   <NavItem eventKey={1} href="/home">
      NavItem 1 content
   </NavItem>
   <NavItem eventKey={2} title="Item">
      NavItem 2 content
   </NavItem>
   <NavItem eventKey={3} disabled>
      NavItem 3 content
   </NavItem>
</Nav>

react-router主要是靠Link to url對應到Route path,再進行components的切換。主要問題,當我們bootstrap的UI對到router要如何嵌入,NavItem href與Link to都需指到對應路徑,該如何結合在一起?
Basic
https://reacttraining.com/react-router/web/example/basic

react-router basic
<Router>
   <div>
      <ul>
         <li>
            <Link to="/">Home</Link>
         </li>
         <li>
            <Link to="/about">About</Link>
         </li>
         <li>
            <Link to="/topics">Topics</Link>
         </li>
      </ul>
      <hr/>
      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
      <Route path="/topics" component={Topics}/>
   </div>
</Router>

react-bootstrp & react-router = react-router-bootstrap
我們的救星就是react-router-bootstrap,它整合React Router v4和React Bootstrap,我們可以直接利用這套件把bootstrap和router直接串起來。LinkContainer等於Nav Link,可以把bootstrap嵌在裡面解決問題。

react-router-bootstrap
https://github.com/react-bootstrap/react-router-bootstrap

React Bootstrap component
<Button href="/foo/bar">Foo</Button>

becomes
<LinkContainer to="/foo/bar">
  <Button>Foo</Button>
</LinkContainer>

react-bootstrp & react-router & react-router-bootstrap = Layout.js

src/components/Layout.js

import React, { Component } from 'react';
import {Navbar, Nav, NavItem, Grid, Row, Col} from 'react-bootstrap'
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
import {LinkContainer} from 'react-router-bootstrap';
import Notices from './Notices';
import UserInfo from './UserInfo';
import PhoneInfo from './PhoneInfo';

class Layout extends React.Component {
  constructor(props) {
    super(props);
    this.state = { active: 1 };
    this.handleSelect = this.handleSelect.bind(this);
  }

  handleSelect(selectedKey) {
    this.setState({active: selectedKey});
  }

  render() {
    const sidebar = {
      position: 'fixed',
      top: '51px',
      bottom: '0',
      left: '0',
      zIndex: '1000',
      display: 'block',
      padding: '20px',
      overflowX: 'hidden',
      overflowY: 'auto',
      backgroundColor: '#f5f5f5',
      borderRight: '1px solid #eee'
    };
    return (
      <Router>
        <div>
          <Navbar fluid={true}>
            <Navbar.Header>
              <Navbar.Brand>
                <a href="/">React-Bootstrap</a>
              </Navbar.Brand>
            </Navbar.Header>
          </Navbar>
          <Grid fluid={true}>
            <Row className="show-grid">
              <Col xs={2} style={sidebar}>
                <Nav stacked activeKey={this.state.active} onSelect={this.handleSelect}>
                  <LinkContainer to="/userinfo">
                    <NavItem eventKey={1}>使用者清單</NavItem>
                  </LinkContainer>
                  <LinkContainer to="/phoneinfo">
                    <NavItem eventKey={2}>電話清單</NavItem>
                  </LinkContainer>
                  <LinkContainer to="/remakeinfo">
                    <NavItem eventKey={3} disabled>備註清單</NavItem>
                  </LinkContainer>
                </Nav>
              </Col>
              <Col xs={10} xsOffset={2}>
                <Route exact path="/" component={Notices}/>
                <Route path="/userinfo" component={UserInfo}/>
                <Route path="/phoneinfo" component={PhoneInfo}/>
              </Col>
            </Row>
          </Grid>
        </div>
      </Router>
    );
  }
}

export default Layout;

今天我們先把主要layout實作出來,明天再繼續實作剩下的components,到時再把所有程式放到git供大家參考。大家應該有發現Layout.js有個小問題,style是直接當成物件傳入假設今天有很多客製style呢?以往我們會把css寫成檔案再導入使用,因為我們目前webpack沒有使用css-loader所以無法處理,待其它components完成再進行調整。


上一篇
DAY21:React實作小專案(分析規劃)
下一篇
DAY23:React實作小專案(components實作)
系列文
30天React從入門到入坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言