好 昨天我們把整個專案架構大概地看了一次 今天就來了解一下
Header 與 LeftDrawer 在 React Component 裡面是如何變出來的
首先,我們先看一下 Header的部分
先看我們import哪些東西進來
// loading Library
import React, {PropTypes} from 'react';
import {Link} from 'react-router';
// Material UI
import AppBar from 'material-ui/AppBar';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
// Material UI Icon
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import Menu from 'material-ui/svg-icons/navigation/menu';
import ViewModule from 'material-ui/svg-icons/action/view-module';
// Material Color
import {white} from 'material-ui/styles/colors';
// Component
import SearchBox from '../SearchBox';
// Style Config
import style from '../../styleConfig/HeaderPage';
library & Material UI 我們就不多說的 那個就是你設計 或者是網路上看到人家怎麼用 你就可以依樣畫葫蘆的放進來
Component 中的 SearchBox 則是表頭上我有做搜尋的功能
最後則是 屬於HeaderComponent 的樣式表
附上一張長相的畫面
好我們繼續往下面看 render()
render() {
const {styles, handleChangeRequestNavDrawer} = this.props;
return (
<div>
<AppBar
style={{...styles, ...style.appBar}}
title={
<SearchBox />
}
iconElementLeft={
<IconButton style={style.menuButton} onClick={handleChangeRequestNavDrawer}>
<Menu color={white} />
</IconButton>
}
iconElementRight={
<div style={style.iconsRightContainer}>
<IconMenu color={white}
iconButtonElement={
<IconButton><ViewModule color={white}/></IconButton>
}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
anchorOrigin={{horizontal: 'right', vertical: 'top'}}
>
<MenuItem key={1} primaryText="Application 1"/>
<MenuItem key={2} primaryText="Application 2"/>
<MenuItem key={3} primaryText="Application 3"/>
</IconMenu>
<IconMenu color={white}
iconButtonElement={
<IconButton><MoreVertIcon color={white}/></IconButton>
}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
anchorOrigin={{horizontal: 'right', vertical: 'top'}}
>
<MenuItem>
<div onClick={() => {this.props.onSubmitLogout()} }>Sign Out</div>
</MenuItem>
</IconMenu>
</div>
}
/>
</div>
);
}
props 傳進來的部份是 上一層預計要改動這一層Header的樣式 還有Header Component 預計傳出去的動作,這個後面我們會再提起
然後再來就是Material UI的應用
最後我們來看一下 登出的方法,這裏是預計去呼叫 Redux 裡面有排定的方法
因為登出我們要去對 State tree 做資料的重置
然後,我們在 App Component 裡面實作這個Header Layout
一樣,你需要把要用的東西import
// Initial Library
import React, {
PropTypes
} from 'react';
// Material UI Library
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import withWidth, {
LARGE,
SMALL
} from 'material-ui/utils/withWidth';
// Components
import Header from '../../containers/HeaderPage';
import LeftDrawer from '../../components/LeftDrawer';
import HomePage from '../../components/HomePage';
// Configuration Files
import ThemeDefault from '../../themeConfig';
// i18n File
import { translate } from 'react-i18next';
這裏載入三個component
Header 表頭
LeftDrawer 左側選單
HomePage 未登入狀態下 看到的首頁頁面
// 承接Container 傳送過來的物件
constructor(props){
super(props);
this.state = {
_IsDrawerOpen: true
};
}
constructor 的重點就是我們設定一個狀態 這個狀態就是預設寄來 左側選單是開啟的
然侯 就像我註解寫的這樣 這地方就是在判斷當螢幕變大變小的時候 我們的選單要如何去因應
componentWillReceiveProps(nextProps) {
console.log("thisPropsWidth: " + this.props.width);
console.log("nextProps: " + nextProps.width);
// 當元件因為螢幕大小被通知改變時,去判斷如果是變大的話再打開menu,反之如果變小,就要關閉menu
if (this.props.width !== nextProps.width) {
this.setState({
_IsDrawerOpen: nextProps.width === LARGE
});
}
}
再來是 這個我們剛剛要傳去給 Header 作為 props的方法
handleChangeRequestNavDrawer() {
this.setState({
_IsDrawerOpen: !this.state._IsDrawerOpen
});
}
簡單說就是你在 Header Component 裡面 也可以來控制這一層的東西
不過呢 這裏你應該會覺得很奇怪 幹嘛不把它放到 Redux 控制的 state tree 呢
幹嘛要這樣用 props 去傳
原因很簡單 我覺得這個不會到處大家都需要控制 所以我就暫時用這個寫法 或許後續有需要 我們再把它搬過去就可以
最後 我們來看 render() 的部分
首先 我們登入的方法還沒有介紹 不過簡單說 這裏的判斷就是根據 localstorage 裡面的 _IsLogin
作為 render 畫面的選擇
透過先 var _ResultPage 然後利用 _IsLogin 值的判斷 來做回傳component 的決定
最後再把它 return
render() {
const { t } = this.props;
// 測試利用localStorage 判斷是否有登入
// 測試 localStorage 設定方式 localStorage.setItem("LoginData", JSON.stringify({'IsLogin':true}))
// 清除 localStorage.clear()
var _LoginData = JSON.parse(localStorage.getItem("LoginData"));
var _IsLogin = false;
var _ResultPage;
if (_LoginData != null) { _IsLogin = _LoginData.IsLogin; }
// 樣式部分
const paddingLeftDrawerOpen = 236;
const styles = {
header: {
paddingLeft: this.state._IsDrawerOpen ? paddingLeftDrawerOpen : 0
},
container: {
margin: '80px 20px 20px 15px',
paddingLeft: this.state._IsDrawerOpen && this.props.width !== SMALL ? paddingLeftDrawerOpen : 0
}
};
// 判斷登入狀態決定回傳component
if (_IsLogin) {
_ResultPage = <MuiThemeProvider muiTheme={ThemeDefault}>
<div>
<Header styles={styles.header}
handleChangeRequestNavDrawer={this.handleChangeRequestNavDrawer.bind(this)}>
</Header>
<LeftDrawer navDrawerOpen={this.state._IsDrawerOpen}
menus={Data.menus}
username="User Admin">
</LeftDrawer>
<div style={styles.container}>
{this.props.children}
</div>
</div>
</MuiThemeProvider>
} else {
_ResultPage = <HomePage></HomePage>
}
return (
<div>
{_ResultPage}
</div>
);
}
最後 定義一下你傳進來的東西 然後把它完整的 export 出去 完成~
App.propTypes = {
children: PropTypes.element,
width: PropTypes.number
};
export default withWidth()(App);