• 【React】 第九部分 react 路由


    React】 第九部分 react 路由



    9. react 路由

    9.1 路由基本使用

    下载react-router-dom : npm install --save react-router-dom@5

    在原生中是依靠a标签实现跳转页面,而在react中是依靠路由链接进行切换组件

    在使用路由链接的时候需要注意 : 最外层需要包裹BrowserRouter或者HashRouter,最后会说两个路由器的区别

    因为整个引用只能归一个路由器管

    import React, { Component } from 'react'
    import Home from '../../pages/Home/Home'
    import About from '../../pages/About/About'
    import { Link, Route,BrowserRouter } from "react-router-dom"
    export default class Header extends Component {
        render() {
            return (
                <div>
                    <BrowserRouter>
                        <div className="row">
                            <div className="col-xs-offset-2 col-xs-8">
                                <div className="page-header"><h2>React Router Demo</h2></div>
                            </div>
                        </div>
                        <div className="row">
                            <div className="col-xs-2 col-xs-offset-2">
                                <div className="list-group">
                                    {/* 使用路由链接,to表示的是要跳转的路径 */}
                                    <Link className="list-group-item" to="/about">About</Link>
                                    <Link className="list-group-item" to="/home">Home</Link>
                                </div>
                            </div>
                        </div>
                        <div className="col-xs-6">
                        {/* 
                            注册路由
                                path:表示匹配的路径
                                component:组件
                        */}
                            <Route path="/about" component={About} />
                            <Route path="/home" component={Home} />
                        </div>
                    </BrowserRouter>
                </div>
            )
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    9.2 一般组件和路由组件的区别

    1. 写法不同:

      • 一般组件:
      • 路由组件: }/>
    2. 存放的位置不同:

      • 一般组件:写在components文件夹下
      • 路由组件:写在pages文件夹下
    3. 接收到的props参数不同:

      • 一般组件:写组件标签的时候,传入什么,就接收到什么

      • 路由组件:可以接收到三个固定的属性

      • history:
            go: ƒ go(n)
            goBack: ƒ goBack()
            goForward: ƒ goForward()
            push: ƒ push(path, state)
            replace: ƒ replace(path, state)
        
        location:
            pathname: "/home"
            search: ""
            state: undefined
        
        match:
            params: {}
            path: "/home"
            url: "/home"
        
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17

    9.3 NavLink组件的使用以及二次封装

    NavLink是Link路由组件的升级版

    作用:当该组件被触发的时候会给追加一个类名默认为active

    activeClassName="xxx" 这个属性可以用来去修改默认类名

    export default class Header extends Component {
        render() {
            return (
                <div>
                    <BrowserRouter>
                        <div className="row">
                            <div className="col-xs-offset-2 col-xs-8">
                                <div className="page-header"><h2>React Router Demo</h2></div>
                            </div>
                        </div>
                        <div className="row">
                            <div className="col-xs-2 col-xs-offset-2">
                                <div className="list-group">
                                    {/* 使用NavLink,to表示的是要跳转的路径 */}
                                    <NavLink activeClassName='hidden' className="list-group-item" to="/about">About</NavLink>
                                    <NavLink className="list-group-item" to="/home">Home</NavLink>
                                </div>
                            </div>
                        </div>
                        <div className="col-xs-6">
                            {/* 
                            注册路由
                                path:表示匹配的路径
                                component:组件
                        */}
                            <div className="panel">
                                <div className="panel-body">
                                    <Route path="/about" component={About}></Route>
                                    <Route path="/home" component={Home}></Route>
                                </div>
                            </div>
                        </div>
                    </BrowserRouter>
                </div>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    根据需要对NavLink进行二次封装

    import React, { Component } from 'react'
    import {NavLink} from "react-router-dom"
    export default class MyNavLink extends Component {
      render() {
        return (
            // 举个例子有公共的高亮样式和公共的类,其他通过props传入
            /*
                知识点:
                    通过props,标签属性传入key:value形式,props就能够接收到指定的key:value
                    那么标签体,props其实也是可以接收到,只不过它给我们固定的一个key,名为children 
             */
           <NavLink activeClassName='active' className="list-group-item" {...this.props}>{this.props.children}</NavLink>
        )
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    // 二者可以对比一下
    <NavLink activeClassName='active' className="list-group-item" to="/about">AboutNavLink>
    <NavLink activeClassName='active' className="list-group-item" to="/about">AboutNavLink>
    
    <MyNavLink to="/about">AboutMyNavLink>
    <MyNavLink to="/home">HomeMyNavLink>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9.4 Switch组件的使用

    作用:Switch能够提高匹配路由的效率

    那么被Switch组件包裹后,只要匹配到第一个对应的路由那么就会停止匹配

    <Switch>
      	<Route path="/about" component={About}></Route>
    	<Route path="/a" component={A}></Route>
    	<Route path="/B" component={B}></Route>
    	<Route path="/about" component={About}></Route>
    </Switch>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    9.5 解决多级路径刷新页面样式丢失的问题

    方法一:

    ​ 在public/index.html中引入样式的时候不写.//

    方法二:

    ​ 在public/index.html中引入样式的时候不写./%PUBLIC_URL%

    方法三:

    ​ 使用HashRouter

    9.6 Redirect 组件的使用

    作用:重定向路由,当没有匹配到任何的路由时,跳转到Redirect所指定的路由

    一般写在注册路由的最下方

    <Switch>
      <Route path="/about" component={About}></Route>
    	<Route path="/home" component={Home}></Route>
    	<Redirect to="/about" />
    </Switch>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    9.7 嵌套路由

    嵌套路由需要注意的点:

    1. 在注册子路由的时候需要在前面加上父路由的path值
    2. 路由的匹配是按照注册路由的顺序进行的
    3. 简单来说,父路由先有才会有子路由
    export default class Home extends Component {
        render() {
            return (
                <div>
                    <h3>我是Home的内容</h3>
                    <div>
                        <ul className="nav nav-tabs">
                            <li>
                                <MyNavLink to="/home/news">News</MyNavLink>
                            </li>
                            <li>
                                <MyNavLink to="/home/message">Message</MyNavLink>
                            </li>
                        </ul>            
                    </div>
                    {/* 注册子路由 */}
                    <Switch>
                        <Route path="/home/news" component={News}/>
                        <Route path="/home/message" component={Message}/>
                        <Redirect to="/home/news"/>
                    </Switch>
                </div>
            )
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    9.8 向路由组件传递params参数

    步骤:

    1. 在路径中携带好params参数

    2. 通过 :xxx 声明params参数

    3. 传入的params参数,可以用this.props.match.params进行接收
      在这里插入图片描述

    export default class Message extends Component {
        state = {
            messageList:[
                {id:1,title:'消息1'},
                {id:2,title:'消息2'},
                {id:3,title:'消息3'},
            ]
        }
        render() {
            return (
                <ul>
                    {
                        this.state.messageList.map((item)=>{
                            return (
                                <li key={item.id}>
                                    {/* 传params参数 */}
                                    <Link to={`/home/message/detail/${item.id}/${item.title}`}>{item.title}</Link>
                                </li>
                            )
                        })
                    }
                    {/* 
                        注册路由
                            在这里需要声明params参数
                            :xx 相当于占位
                     */}
                    <Route path="/home/message/detail/:id/:title" component={Detail}/>
                </ul>
            )
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    9.9 向路由组件传递search参数

    步骤:

    1. 在路径中携带好search参数

    2. 传search参数,其实就是query参数 以 ? 开头 & 进行串联, 形式是key:value

    3. 需要注意的是seach参数,react没有像params参数那样帮我们整理好,接收的方式this.props.location.search

      获取到的数据类似?id=2&title=消息2,所以可以自己写一个函数去整理得到的参数

    在这里插入图片描述

    export default class Message extends Component {
        state = {
            messageList:[
                {id:1,title:'消息1'},
                {id:2,title:'消息2'},
                {id:3,title:'消息3'},
            ]
        }
        render() {
            return (
                <ul>
                    {
                        this.state.messageList.map((item)=>{
                            return (
                                <li key={item.id}>
                                    {/* 
                                        传search参数,其实就是query参数 
                                        以 ? 开头 & 进行串联
                                    */}
                                    <Link to={`/home/message/detail?id=${item.id}&title=${item.title}`}>{item.title}</Link>
                                </li>
                            )
                        })
                    }
                    {/* 
                        注册路由:
                            在这里不需要声明search参数
                     */}
                    <Route path="/home/message/detail" component={Detail}/>
                </ul>
            )
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    9.10 向路由组件传递state参数

    步骤:

    1. 在路径中携带好state参数,以对象的形式

    2. 和上述两个参数不同在于:传入的参数不会展示在地址栏

    3. 刷新页面也不会丢失

    在这里插入图片描述

    import React, { Component } from 'react'
    import {Link, Route} from "react-router-dom"
    import Detail from './Detail/Detail'
    export default class Message extends Component {
        state = {
            messageList:[
                {id:1,title:'消息1'},
                {id:2,title:'消息2'},
                {id:3,title:'消息3'},
            ]
        }
        render() {
            return (
                <ul>
                    {
                        this.state.messageList.map((item)=>{
                            return (
                                <li key={item.id}>
                                    {/*
                                        传state参数 ,以对象的形式
                                     */}
                                    <Link to={{pathname:'/home/message/detail',state:{id:item.id,title:item.title}}}>{item.title}</Link>
                                </li>
                            )
                        })
                    }
                    {/* 
                        注册路由:
                            在这里不需要声明state参数
                     */}
                    <Route path="/home/message/detail" component={Detail}/>
                </ul>
            )
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    9.11 push和replace

    push模式 :浏览器可以进行回退(默认开启push模式)

    replace模式: 不能进行回退

    {item.title}
    
    • 1

    9.12 编程式路由导航

    编程式路由导航的使用方法基本差不多

    说白了就是通过去调用this.props.history下的API对路由跳转进行控制

     handlePush = (id,title) =>{
            /* 
                可以参两个参数
                    - 第一个参数是路径
                    - 第二个参数是state
            */
            // push跳转携带params参数    
            this.props.history.push(`/home/message/detail/${id}/${title}`)
    
            // push跳转携带search参数
            this.props.history.push(`/home/message/detail/?id=${id}&title=${title}`)
    
            // push跳转携带state参数
            this.props.history.push('/home/message/detail',{id,title})
        }
    
        handleReplace = (id,title) =>{
             /* 
                可以参两个参数
                    - 第一个参数是路径
                    - 第二个参数是state
            */
            // replace跳转携带params参数    
            this.props.history.replace(`/home/message/detail/${id}/${title}`)
    
            // replace跳转携带search参数
            this.props.history.replace(`/home/message/detail/?id=${id}&title=${title}`)
    
            // replace跳转携带state参数
            this.props.history.replace('/home/message/detail',{id,title})
        }
        
        handleGo = () =>{
          	// 可以传入参数,正数表示向前跳转2次
          	// 可以传入参数,负数表示向后跳转2次
            this.props.history.go(2)
          	this.props.history.go(-2)
        }
    
        handleGoBack = () =>{
          	// 后退一次
            this.props.history.goBack()
        }
    
        handleGoForward = () =>{
          	// 前进一次
            this.props.history.goForward()     
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    9.13 withRouter

    作用 : 可以加工一般组件,让一般组件拥有路由组件特有的API

    在9.2有述说一般组件和路由组件的不同之处,其中最主要的区别就是接收到的props参数不同

    import {withRouter} from 'react-router-dom'
    class Header extends Component {
        render() {
            console.log(this.props);
            return (
                <div>
                </div>
            )
        }
    }
    
    export default withRouter(Header)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    9.14 BrowserRouter与HashRouter的区别

    1. 底层原理不一样:

      BrowserRouter使用的是H5的 history API,不兼容IE9以下的版本

      HashRouter使用的是URL的哈希值

    2. path表现得形式不一样:

      BrowserRouter的路径中没有#,例如:localhost:3000/demo/test

      HashRouter的路径中有#,例如:localhost:3000/#/demo/test

    3. 刷新后对路由state参数的影响:

      BrowserRouter没有任何的影响,因为state保存在history对象中

      HashRouter刷新后会导致路由state参数的丢失

    4. HashRouter可以用于解决一些路径错误相关的问题


    总结

    以上就是今天要讲的内容,希望对大家有所帮助!!!

  • 相关阅读:
    vue2+echarts:后台传递一天有多类数据的时候,如何渲染柱状图
    【Socket】解决TCP粘包问题
    科技云报道:大模型会给操作系统带来什么样的想象?
    node 第十一天 纯使用第三方cookie 实现 跨源单点登录(或者说免登录) 以及白话说cookie的跟踪原理
    【项目管理/PMP/PMBOK第六版/第七版/新考纲】PMP错题解析 | 沟通管理计划、变更请求、审计、激励、培训、Y理论、团队建设、风险登记册、项目章程
    自动化测试框架pytest命令参数
    CSS:filter(滤镜)属性
    day22集合01
    Linux服务管理--服务分类
    【python】OpenCV—Age and Gender Classification
  • 原文地址:https://blog.csdn.net/Trees__/article/details/126285567