iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
0

好 昨天我們把整個專案架構大概地看了一次 今天就來了解一下
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 的樣式表

附上一張長相的畫面
https://ithelp.ithome.com.tw/upload/images/20171223/20107767TvaSjDBl7N.png

好我們繼續往下面看 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);

上一篇
【Day 4】The Detail Structure Of My React.js Project
下一篇
【Day 6】The implementation of Sign In & Out
系列文
React.js & Laravel 30天訓練30

尚未有邦友留言

立即登入留言