zoukankan      html  css  js  c++  java
  • react路由心得总结

    1引入react-router-dom包(前面属讲解部分,可以直接拉至下方看demo)

        npm install react-router-dom --save
    或者 yarn add react-router-dom
    

    2 创建并暴露router.js文件,并在index.js里引入,之后在其他页面使用Link便可。页面模板如下

    这是index.js页面
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import Router from './router.js';
    import * as serviceWorker from './serviceWorker';
    
    ReactDOM.render(<Router/>, document.getElementById('root'));   /* 这里引入的是Router而不是router.js页面暴露出的IRouter */
    serviceWorker.unregister();
    
    这是router.js页面
    
    import React from 'react';
    import {BrowserRouter,Route,Switch} from 'react-router-dom';   
    /* 引入BrowserRouter,Route,Switch等 */
    
    import MissionCowry from './mission-cowry/mission-cowry.js';    
    /* 引入父页面组件——子页面组件的内容会渲染到父页面组件里,子页面组件内容即Link之后的{this.props.children} */
    
    import MissionManage from './mission-cowry/mission-manage/mission-manage.js';  
    /* 引入子页面组件 */
    import PosterManage from './mission-cowry/poster-manage/poster-manage.js';
    import PosterAdd from './mission-cowry/poster-manage/poster-add.js';
    import ActivityData from './mission-cowry/activity-data/activity-data.js';
    import AllRecord from './mission-cowry/score-shop/all-record.js';
    import CommodityManage from './mission-cowry/score-shop/commodity-manage.js';
    
    export default class IRouter extends React.Component {   
    //其实这里Irouter,Erouter,Crouter命名是比较随意,只要不用Router命名就行
        render(){
            return(
                      //---布置路由---
                <BrowserRouter>    //最外层用BrowserRouter包裹,有时也可以是HashRouter等
                    <MissionCowry>  //外层用父页面组件包裹
                        <Switch>  //Switch即从上往下查找,找到了即终止查找
                            <Route path='/mission-manage/mission-manage.js' component={MissionManage} />  
                              //path地址要从父页面(./mission-cowry)的下一层目录开始 ,有时要带js后缀有时反而就不能带,这里有点不懂。
                            <Route exact={true} path='/poster-manage/poster-manage.js' component={PosterManage} />  //exact="true" 精准跳转
                            <Route path='/poster-manage/poster-add.js' component={PosterAdd} /> 
                            <Route path='/activity-data/activity-data.js' component={ActivityData} />
                            <Route path='/score-shop/all-record.js' component={AllRecord} />
                            <Route path='/score-shop/commodity-manage.js' component={CommodityManage} />
                        </Switch>
                    </MissionCowry>
                </BrowserRouter>
            );
        }
    }
    
    这是导航菜单页面,或者说跳转按钮所在的页面
    
    import React from 'react';
    import '../comp.less';
    import {Link} from 'react-router-dom';   /* 这里要引入Link */
    
    import {Layout,Menu,Breadcrumb,Icon,Divider} from 'antd';
    const {SubMenu} = Menu;
    const {Header,Content,Sider} = Layout;
    export default class MissionCowry extends React.Component{
        render(){
            return(
                <div className="LinkDemo">
                    <Layout>
                    <Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse} className="mainsider">
                        <Menu theme="dark" defaultSelectedKeys={['sub2-1']} defaultOpenKeys={["sub2"]} mode="inline">
                            <Menu.Item key="1">
                                <Link to="/poster-manage/poster-manage.js"><span>海报管理</span></Link>
                            </Menu.Item>
                            <Menu.Item key="2">
                                <Link to="/mission-manage/mission-manage.js"><span>任务管理</span></Link> 
                            </Menu.Item>
                            <SubMenu key="sub1" title={<span><Icon type="paper-clip" /><span><Link></Link>积分商城</span></span>}>
                                <Menu.Item key="sub1-1"><Link to="/score-shop/commodity-manage.js">商品管理</Link></Menu.Item>
                                <Menu.Item key="sub1-2"><Link to="/score-shop/realthings-record.js">实物记录</Link></Menu.Item>
                            </SubMenu>
                            <Menu.Item key="3">
                                <Link to="/activity-data/activity-data.js"><span>活动数据</span></Link>
                            </Menu.Item>
                        </Menu>
                    </Sider>
                        <Layout>
                            <Content className="maincontent">
                                {this.props.children}  
                        //这是路由导入的子页面组件的内容,这里把它放在Content里呈现
                            </Content>
                        </Layout>
                    </Layout>
                </div>
            );
        }
    }
    
    其他页面需要路由跳转的话
    
    先将需要跳转到的页面在router.js里导入并布置路由
    再在当前页面使用Link写一下跳转格式就OK了
    
    如:点击"添加商品"跳转到商品添加页
    <Link to="/commodity-manage/commodity-add.js"><Button ><span>添加海报</span></Button></Link>
    
    嵌套路由怎么理解?怎么使用?参考以下几个页面
    ——————————————————————————————————————————————
    router.js页面
    import React from 'react'
    import {HashRouter as Router,Route,LinK} from 'react-router-dom'
    import Main from './Main'
    import About from './../route1/about'
    import Topic from './../route1/topic'
    import Home from './Home'
    export default class IRouter extends React.Component{
    
        render(){
            return (
                <Router>
                    <Home>
                        <Route path="/main" render={()=>
                            <Main>
                                <Route path="/main/a" component={About}></Route>
                            </Main>   
                        }></Route>
                        <Route path="/about" component={About}></Route>
                        <Route path="/topics" component={Topic}></Route>
                    </Home>
                </Router>
            );
        }
    }
    
    ——————————————————————————————————————————————
    
    Main.js页面
    import React from 'react'
    import { Link } from 'react-router-dom'
    export default class Main extends React.Component {
    
        render() {
            return (
                <div>
                    this is main page.
                    <Link to="/main/a">嵌套路由</Link>
                    <hr/>
                    {this.props.children}     //记住嵌套路由也一定别忘记了this.props.children
                </div>
            );
        }
    }
    
    ——————————————————————————————————————————————
    
    Home.js页面
    import React from 'react'
    import { Link } from 'react-router-dom'
    export default class Home extends React.Component {
    
        render() {
            return (
                <div>
                    <ul>
                        <li>
                            <Link to="/main">Home1</Link>
                        </li>
                        <li>
                            <Link to="/about">About1</Link>
                        </li>
                        <li>
                            <Link to="/topics">Topics1</Link>
                        </li>
                    </ul>
                    <hr />
                    {this.props.children}
                </div>
            );
        }
    }
    

    嵌套路由样式共用

    嵌套路由,如果在父页面中引入子页面组件。那么子页面组件也就是父页面的一部分了,此时子页面组件是享有父页面的css样式的
    例:
    1 父页面引入了子页面组件
    2 父页面div定义了className="header",子页面组件div定义了className="header"
    3 父页面引入了comp.less,子页面未引入
    4 comp.less里定义了.header{200px; height:100px; backgoundcolor:red;}
    4 该样式在子页面组件里同样生效
    注意:这个可能会带来样式冲突问题,所以在定义父页面以及子页面className的时候,要尽量保证命名不要重复
    
    src
      |__demo
      |         |__subdemo1.js
      |         |__subdemo2.js
      |         |__subdemo1-sub1.js
      |         |__subdemo1-sub2.js
      |__router.js
    
    如目录所示,subdemo1-sub1.js和subdemo1-sub2.js是subdemo1.js的子页面组件。
    但是!!它们却放在了同一文件夹(demo)下,那路由路径怎么解决呢
    以下是router.js里的部分代码
    
    
    import SubDemo1 from './demo/subdemo1.js'    //看到没有,import是按照文件所在路径正常引入的,这些文件都在demo文件夹下
    import SubDemo1Sub1 from './demo/subdemo1-sub1.js'
    import SubDemo1Sub1 from './demo/subdemo1-sub2.js'
    
    <Link to="/demo/subdemo1/subdemo1-sub1">按钮1</Link>     //但是这里就不一样了,subdemo1-sub1层级是在subdemo1之下的,所以这里是 subdemo1/subdemo1-sub1
    <Link to="/demo/subdemo1/subdemo1-sub2">按钮2</Link> 
    <Route path="/demo/subdemo1"  
                  render= { ()=>
                                 <SubDemo1>
                                    <Route path="/demo/subdemo1/subdemo1-sub1" component={SubDemo1Sub1} />  //还有这里,这里的path和Link方式是一样的
                                    <Route path="/demo/subdemo1/subdemo1-sub2" component={SubDemo1Sub2} />
                                </SubDemo1>   
                                }    
     />
    
    PS:对,没错,就是这样,就算在同一目录下,如果层级不同,path,Link路径引入还是要按照文件层级上下级来执行的,当然import的路径就不是这样了
    
    

    默认路由

    src
    |__demo       //demo1-sub1.js是demo1-index.js的子页面,虽然在同一个文件夹下,但是路径却是上下级关系
              |__demo1
              |         |__demo1-index.js
              |         |__demo1-sub1.js
              |         |__demo1-sub2.js
              |__setting.js
              |__demo2
                        |__demo2-index.js
                        |__demo2-sub1.js
                        |__demo2-sub2.js
    
    <Switch>
             <Route path={`/demo/setting`} exact component={ Setting } />
             <Route path="/demo/demo1/demo1-index/demo1-sub1" component={Demo1Sub1} />  
                      
             <Route path="/demo/demo2/demo2-index"   
                        render={()=>
                          <Demo2Index>
                            <Switch>                   //——默认路由第 1 点,Switch语句——
                              <Route path="/demo/demo2/demo2-index" exact  component={Demo2Sub1} />    //——默认路由第 2 点,默认路由给个exact={true}精准查找,path引入的是父页面路径,component是子页面组件——
                              <Route path="/demo/demo2/demo2-index/demo2-sub2" component={Demo2Sub2} />
                              <Redirect path="/demo/demo2/demo2-index" to={{pathname:"/demo/demo2/demo2-index/demo2-sub2"}} /> //——默认路由第 3 点,使用Redirect,path引入的是父页面路径,to引入的是子页面路径(注意是指路由里的路径,而不是文件里的路径,如果算文件里的路径则是/demo/demo2/demo2-sub2,这样是不正确的)——
                            </Switch>
                          </Demo2Index>
                        }
                />
             <Redirect to="/demo/setting" />
     </Switch>
    

    一个完整的默认进入登录页面的router.js(以前的懒得看了,就看这个吧,更直观一些)

    文件目录
    src
    |__api
    |__image
    |__pages
            |__login
            |__commodity
            |__user
            |__allview
            |__index.js
            |__index.less
    |__App.js
    |__router.js
    |__index.js
    |__index.less
    
    === src/App.js页面 ===
    
    import React, { Component } from 'react';
    
    export default class App extends Component {
      render() {
        return (
          <div>
            {this.props.children}   //最顶级路由,用来存放同等级的几个页面如:登录,注册,用户中心
          </div>
        );
      }
    }
    
    === src/index.js页面 ===
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.less';
    - import App from './App';
    + import IRouter from './router';
    import * as serviceWorker from './serviceWorker';
    
    - ReactDOM.render(<App />, document.getElementById('root'));
    + ReactDOM.render(<IRouter />, document.getElementById('root'));
    
    serviceWorker.unregister();
    
    
    
    
    
    === src/router.js页面 ===
    
    import React from 'react';
    import {BrowserRouter,Route,Switch,Redirect} from 'react-router-dom';   
    
    import App from './App'   //注意react脚手架里面,这个App是大写开头的
    
    //登录注册部分
    import Login from './pages/login/login'  //登录
    import Register from './pages/login/register'  //注册
    
    //用户中心
    import UserCenterIndex from './pages/index'   //主页面
    
    //首页部分
    import Overview from './pages/allview/overview'   //概览
    
    //用户部分
    import userInfo from './pages/user/userInfo'  //用户-用户信息
    import userStatis from './pages/user/userStatis'  //用户-用户统计
    
    //商品部分
    import CommodityList from './pages/commodity/commodityList'   //商品-商品列表
    import CommodityPrice from './pages/commodity/commodityPrice' //商品-商品价格
    
    export default class IRouter extends React.Component{
    
        render(){
    
            return(
                <BrowserRouter>
                    <App>   //最顶级路由,下面包裹所有子路由
                        <Switch>
                            {/* 登录注册 */}
                            <Route path="/pages/login/login" exact component={Login} />       //登录,注册,用户中心这几个路由都是平级的
                            <Route path="/pages/login/register" component={Register} />
                           
                            <Route path="/pages"  render={()=>    //这一行要注意,解析在下面①
                                    <UserCenterIndex>   {/* 用户中心 */}
                                        <Switch>
                                            {/* 概览部分 */}
                                            <Route path="/pages/allview/overview" component={Overview} />
                        
                                            {/* 用户部分 */}
                                            <Route path="/pages/user/userInfo" component={userInfo} />
                                            <Route path="/pages/user/userStatis" component={userStatis} />
                                    
                                            {/* 商品部分 */}
                                            <Route path="/pages/commodity/commodityList" component={CommodityList} />
                                            <Route path="/pages/commodity/commodityPrice" component={CommodityPrice} />
                                        </Switch>
                                    </UserCenterIndex>
                               } />
                            
                            <Redirect to="/pages/login/login" />   //这句代码的作用是,将localhost://3000/pages/login/login设置为默认路由   ②Redirect用法
                        </Switch>
                    </App>
                </BrowserRouter>
            );
        }
    }
    
    ① 这里需要讲解一下,"/"相当于最高级路由,如果这里是path="/"而不是path="/pages",那么路由会首先跳转到"/"。
    且如果使用了switch,那么路由在跳转到此路由之后便不再向下跳转。
    这样的结果便是,路由开启后,会默认跳转到用户中心(path="/")而不是登录页面(path="/pages/login/login")。
    因为登录页面的path="/pages......",优先级是低于path="/"的,这里给定了switch,所以路由在跳转到"/"后便不会再往下查找了。
    所以,在命名路由路径时,应尽量让它们的根路径相同。我之前的命名是:
    概览部分:path="/allview/overview"
    用户部分:path="/user/userInfo"   path="/user/userStatis"
    商品部分:path="/commodity/commodityList"   path="/commodity/commodityPrice"
    你看,我这样命名,它们的根路径就完全不相同,那我路由也不好做处理。只能设置path="/"来作为它们的根路由。因为"/"是它们唯一的共同根路由。
    但是我这样设置以后,页面就默认跳转不到登录页面(因为登录页面的根路由是"/pages/....."),而是用户中心,这样就与我的意向背道而驰。
    所以我做了以下改动,我将它们的路由命名改为
    概览部分:path="/pages/allview/overview"
    用户部分:path="/pages/user/userInfo"   path="/pages/user/userStatis"
    商品部分:path="/pages/commodity/commodityList"   path="/pages/commodity/commodityPrice"
    这样,我就能将用户中心的根路由设置为path="/pages",与登录页面的根路由一样。这样,我就可以用Redirect将登录页面设置为默认路由了。
    以上,是可以变通的,不过如果按照我的文件目录搭建习惯来,就这样写就可以了。我的文件目录搭建习惯看我react的另一篇博客:搭建一个react项目
    
    ② 之前有介绍过Redirect设置默认路由用法,那里即需要设置path,有需要to,<Redirect path="" to={{}} />。这里好像<Redirect to="" />就可以了。
    

    在每个模块里创建新的路由分支页面来存放此模块的路由,而不是所有路由都放在一个router.js里,这样不易于管理,router.js里存放每个模块的路由分支页面就可以了

    router.js页面
    import React from 'react';
    import {BrowserRouter,Route,Switch,Redirect} from 'react-router-dom'; 
      
    import App from './App'
    
    import CommodityRouter from './pages/commodity/commodityRouter'   //商品部分的路由分支页面
    
    export default class IRouter extends React.Component{
    
        render(){
    
            return(
                <BrowserRouter>
                    <App>   
                        <Switch>
                            <Route path="/pages/login/login" exact component={Login} />      
                            <Route path="/pages/login/register" component={Register} />
                           
                            <Route path="/pages"  render={()=> 
                                    <UserCenterIndex>  // ⑤⑤,userCenterIndex为父级页面,包裹子级页面
                                        <Switch>
                                            {/* 概览部分 */}
                                            <Route path="/pages/allview/overview" component={Overview} />
    
                                            {/* 商品部分 */}
                                            <Route path="/pages/commodity" component={CommodityRouter} />   //商品模块路由分支,此处path应与⑩处一致(即此模块的首页面)
                                        </Switch>
                                    </UserCenterIndex>
                               } />
                            
                            <Redirect to="/pages/login/login" /> 
                        </Switch>
                    </App>
                </BrowserRouter>
            );
        }
    }
    
    
    commodityRouter.js页面
    import React from 'react';
    import {Route,Switch,Redirect} from 'react-router-dom';
    
    import CommodityIndex from './commodityIndex'  //商品-商品主页
    import CommodityList from './commodityList'  //商品-商品列表
    
    export default class CommodityRouter extends React.Component{
    
        render(){
            return(
                <div>
                    <main>   //强调一下,main为h5新添加,IE浏览器不支持,若项目需兼容IE,则去除main
                        <Switch>
                            <Route path="/pages/commodity" exact component={CommodityIndex} />   // ⑩
                            <Route path="/pages/commodity/commodityList" component={CommodityList} />
                            <Redirect to="/pages/commodity" />
                        </Switch>
                    </main>
                </div>
            );
        }
    }
    
    

    ===== 最新版本 =====

    目录

    ===== src/index.js页面 =====
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.less';
    - import App from './App';
    + import IRouter from './router';
    import * as serviceWorker from './serviceWorker';
    
    - ReactDOM.render(<App />, document.getElementById('root'));
    + ReactDOM.render(<IRouter />, document.getElementById('root'));
    
    serviceWorker.unregister();
    
    
    
    ===== src/App.js页面 =====
    
    import React from 'react';
    
    export default class App extends React.Component{
    
        render(){
            return(
                <div>{this.props.children}</div>
            );
        }
    }
    
    
    
    ===== src/router.js主路由页面 =====
    
    import React from 'react'
    import {BrowserRouter,Route,Switch,Redirect} from 'react-router-dom'
    
    import App from './App'
    
    import UserRouter from './pages/user/userRouter'   //用户中心界面路由
    
    import HomeRouter from './pages/home/homeRouter'  //展示页路由
    
    
    export default class IRouter extends React.Component{
        render(){
            return(
                <BrowserRouter>
                    <App>
    -                    <Switch>   //方式一,路由样式 http://localhost:3000/pages/user
    -                        <Route path="/pages"   //若要将路由定位到/pages/之后,可以使用此方式,即<Route path="/XXXX" render={()=><Switch>...</Switch>} />
    -                            render={()=>
    -                                <Switch>  //若想要将下方路由设置为某一页面的子路由,则使用父级路由包裹即可(见上方 ⑤⑤ 处)
    -                                    <Route path="/pages/user" component={UserRouter} />
    -                                    <Route path="/pages/home" component={HomeRouter} />
    -                                    <Redirect to="/pages/user" />
    -                                </Switch>
    -                        } />
    -                        <Redirect to="/pages" />   //这里也需要重定向到 /XXXX
    -                    </Switch>
    
    +                    <Switch>    //方式二,路由样式 http://localhost:3000/user
    +                        <Route path="/user" component={UserRouter} />  //这里的path需要与路由分支里的主路由一致,如下方的主路由若是/user(见下方 ①⑥ 处),则这里也必须设为/user
    +                        <Route path="/home" component={HomeRouter} />
    +                        <Redirect to="/user" />
    +                    </Switch>
                    </App>
                </BrowserRouter>
            );
        }
    }
    
    ===== src/pages/user/userRouter.js路由分支页面 =====
    
    import React from 'react';
    import {Route,Switch,Redirect} from 'react-router-dom';
    
    import Login from './login'
    import Register from './register'
    
    export default class UserRouter extends React.Component{
    
        render(){
            return(
                <div>
                    <Switch>
                        <Route path="/user" exact component={Login} />  // ①⑥ , 这是此路由分支里的默认路由,/user
                        <Route path="/user/register" component={Register} />    //这是此路由分支里的一般路由,/user/register,注意区别,一般路由相当于默认路由的子路由,要在其后(如这里的/user之后)添加。如/user/register
                        <Redirect to="/user" />
                    </Switch>
                </div>
            )
        }
    }
    
    
    
    ===== src/pages/user/homeRouter.js路由分支页面 =====
    
    import React from 'react';
    import {Route,Switch,Redirect} from 'react-router-dom';
    
    import Home from './home'
    import HomeShow from './homeShow'
    
    export default class HomeRouter extends React.Component{
    
        render(){
            return(
                <div>
                    <Switch>
                        <Route path="/home" exact component={Home} />  
                        <Route path="/home/homeshow" component={HomeShow} />    
                        <Redirect to="/home" />
                    </Switch>
                </div>
            )
        }
    }
    
    
  • 相关阅读:
    eclipse c++
    smb
    osx mount nfs/smb
    0927用的
    0926 隐藏地址栏
    0921笔记
    生成文件并下载
    在线图标
    react redux
    electron
  • 原文地址:https://www.cnblogs.com/huihuihero/p/10834787.html
Copyright © 2011-2022 走看看