項目結構如下:
項目代碼提交網址: https://github.com/xiaohao198623/router.git
index.js代碼吐下:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
app.js代碼吐下:
import React, { Component } from 'react';
import {HashRouter as Router } from 'react-router-dom'
import RouterView from './router/Router'
import Nav from './containers/Nav'
class App extends Component {
componentWillMount (){
console.log('===========app')
console.log(this.props)
}
render() {
return (
<div>
<Router>
<div>
<Nav></Nav>
<RouterView ></RouterView>
</div>
</Router>
</div>
);
}
}
export default App;
nav.js代碼吐下:
import React,{Component} from 'react'
import { Link , withRouter ,NavLink } from 'react-router-dom'
export default class Nav extends Component{
componentWillMount (){
console.log('===========nav')
console.log(this.props)
}
render(){
// console.log(this.props)
return (
<div>
<ul className="nav nav-tabs">
<li role="presentation"><NavLink to={'/'}>首頁</NavLink></li>
<li role="presentation"><NavLink to={'/profile'}>個人中心</NavLink></li>
<li role="presentation"><NavLink to={{pathname:'user' }}>用戶中心</NavLink></li>
</ul>
{/*<button onClick={()=>{ console.log(this.props); this.props.history.push('/profile') }}>測試按鈕</button>*/}
</div>
)
}
}
// export default withRouter(Nav)
Router.js代碼吐下:
import React, {Component} from 'react';
//路由的2種形式: hash(HashRouter) , H5的historyApi(BroswerRouter)是路由的容器,是組件,要包在路由的外面
import { Route, Switch, Redirect } from 'react-router-dom'
// import {Home} from './containers/Home',寫法錯誤,錯誤原因如下解釋
import Home from '../containers/Home'
import Profile from '../containers/Profile'
import User from '../containers/User'
import Details from '../containers/Details'
import ProtectedRouter from '../containers/ProtectedRouter'
export default class RouterView extends Component {
componentWillMount (){
console.log('===========router')
console.log(this.props)
}
render() {
return (
<div className={'container'}>
<div className="row">
<div className="col-md-12">
{/*Switch 讓router匹配後就停止匹配下面的,這個時候訪問下面的3個路由時,出現的都是home組件 */}
<Switch >
{/*exact確切的,表示只有路徑完全相同時,纔會匹配*/}
<Route path='/' exact={true} component={Home}></Route>
<Route path={'/profile'} component={Profile}></Route>
{/*<Route path={'/user'} component={User}></Route>*/}
<ProtectedRouter path={'/user'} component={User}></ProtectedRouter>
{/*進入詳情頁面需要傳入一個id, details/:id this.props.match.params={ id:1 } , ID必須要有;但是可以隨機*/}
<Route path={'/details/:id'} component={Details}></Route>
<Redirect to={'/'}></Redirect>
{/*Redirect具有重定向功能,路由變成首頁路由,如果想路由不變,但是組件仍然指向home,可以這麼實現*/}
{/*<Route component={Home}></Route>*/}
</Switch>
</div>
</div>
</div>
);
}
}
Home.js代碼吐下:
import React,{Component} from 'react'
export default class Home extends Component{
// constructor(){
// super()
// }
render(){
return (
<div>首頁</div>
)
}
}
Profile.js代碼吐下:
import React,{Component} from 'react'
export default class Profile extends Component{
componentWillMount (){
console.log('===========profile')
console.log(this.props)
}
render(){
return (
<div>個人中心</div>
)
}
}
User.js代碼吐下:
import React, {Component} from 'react'
import { Link, Route ,NavLink} from 'react-router-dom'
import Add from '../containers/Add'
import List from '../containers/List'
export default class User extends Component {
render() {
return (
<div className={'container'}>
<div className="row">
<div className="col-md-3">
<ul className="nav nav-staked">
<li role="presentation"><NavLink to={'/user/add'}>添加用戶</NavLink></li>
<li role="presentation"><NavLink to={'/user/list'}>用戶列表</NavLink></li>
</ul>
</div>
<div className="col-md-9">
{/*<Route path={'/user'} exact={true} component={Add}></Route>*/}
<Route path={'/user/add'} component={Add}></Route>
<Route path={'/user/list'} component={List}></Route>
</div>
</div>
</div>
)
}
}
Details.js代碼吐下:
import React,{Component} from 'react'
export default class Details extends Component{
render(){
return (
<div>
{ console.log(this.props) }
<p>{ this.props.match.params.id }</p>
<p>{ this.props.location.state }</p>
</div>
)
}
}
ProtectedRouter.js代碼吐下:
import React,{Component} from 'react'
import { withRouter } from 'react-router-dom'
// withRouter是一個高級組件,使用它之後,可以多出來3個屬性:history , match ,location。路由組件中無須使用它包裹組件;只有非路由組件,跳轉的時候才需要使用它
class ProtectedRouter extends Component{
componentWillMount (){
console.log('===========ProtectedRouter')
console.log(this.props)
let flag=false
if(flag){
this.props.history.push('/')
}
}
render(){
let {path,component:Component}=this.props
return (
<div>
<Component></Component>
</div>
)
}
}
export default withRouter(ProtectedRouter)
Add.js代碼吐下:
import React,{Component} from 'react'
export default class Add extends Component{
componentWillMount (){
console.log('===========add')
console.log(this.props)
}
handleClick=()=>{
let userList= JSON.parse(localStorage.getItem('userList')) || []
userList.push({'userId':Math.random() , 'value':this.x.value})
localStorage.setItem('userList', JSON.stringify(userList) )
//素有通過路由渲染的組件屬性會多出來3個屬性:history,match,loaction
console.log(this.props)
this.props.history.push('/user/list')
}
render(){
return (
<div>
<input type="text" ref={(x)=>{this.x=x}}/>
<button onClick={this.handleClick} >按鈕</button>
</div>
)
}
}
List.js代碼吐下:
import React, {Component} from 'react'
import { Link} from 'react-router-dom'
export default class List extends Component {
handleClick=(index)=>{
console.log(index)
this.props.history.push('/profile')
}
render() {
let userList = JSON.parse(localStorage.getItem('userList')) || []
// console.log(userList)
return (
<div>
<table className="table table-bordered">
<tbody>
<tr>
<th>用戶ID</th>
<th>用戶名稱</th>
<th>跳轉(拼接)</th>
<th>編輯(JSX語法)</th>
<th>函數調用(函數調用)</th>
</tr>
{
userList.map((item, index) => {
return (
<tr key={index}>
<td>{item.userId}</td>
<td>{item.value}</td>
{/*第一種方式:拼接字符串,*/}
<td> <Link to={{
pathname:'/details/'+item.userId ,
//刷新以後,這個狀態就消失了
state:index
}}>編輯</Link> </td>
{/*第二種方式:JSX語法*/}
<td> <Link to={`/details/${item.userId}`}>編輯</Link> </td>
{/*React裏的事件參數傳遞和傳統的JS參數有些不一樣,需要通過bind方法來綁定參數,第一個參數指向this,第二個參數開始纔是事件函數接收到的參數;*/}
<td ><span onClick={this.handleClick.bind(this,index)}>編輯</span> </td>
</tr>
)
})
}
</tbody>
</table>
</div>
)
}
}