react路由使用二

項目結構如下:
這裏寫圖片描述
項目代碼提交網址: 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;
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>
        )
    }
}
發佈了89 篇原創文章 · 獲贊 31 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章