前言

eg:代表代码对照 若文章有误,欢迎读者留言反馈

路由 React-Router V5版本

提前创建pages文件夹里面放几个页面

  1. 根组件一般使用函数组件,也可以使用类组件
  2. 安装插件学习v5.3.0版本路由 npm i -S react-router-dom@5.3.0
  3. App.js需要去入口文件,配置路由模式
  4. 引入页面
  5. 从第三方路由模块中引入Route路由对象当标签使用,Switch标签和Redirect重定向标签
  6. 使用标签配置一级路由【地址栏输入路径默认与这里的path做正则匹配,包含这里path就符合,不加switch会每个都匹配】
  • 通过route这个标签绑定两个属性,建立path 和 component的一个映射关系
  • Switch 指定我们路由匹配规则,提高性能,只匹配一个
  • exact 属性,精确匹配 path完全相等才算成立,二级路由的时候切记使用
  • Switch和exact搭配使用
  1. 重定向加上exact好一点
  2. 404配置 可以省略 path=”*”
  3. 配置二级路由,以home.jsx为例提前创建好两个Demo1.jsx和Demo2.jsx两个页面,去Home.jsx页面去配置

App.js文件代码:

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
import React from 'react'

// 提前创建pages文件夹里面放几个页面
// 1. 根组件一般使用函数组件,也可以使用类组件
// 2. 安装插件学习v5.3.0版本路由 npm i -S react-router-dom@5.3.0
// 3. App.js需要去入口文件,配置路由模式
// 4. 引入页面
import My from './pages/My'
import Home from './pages/Home'
import User from './pages/User'
import NotFound from './pages/NotFound'
// 5. 从第三方路由模块中引入Route路由对象当标签使用,Switch标签和Redirect重定向标签
import { Switch, Route, Redirect } from 'react-router-dom'
const App = () => {
return (
<div>
<h3>React V5路由学习</h3>
{/*
6. 使用标签配置一级路由【地址栏输入路径默认与这里的path做正则匹配,包含这里path就符合,不加switch会每个都匹配】
通过route这个标签绑定两个属性,建立path 和 component的一个映射关系
Switch 指定我们路由匹配规则,提高性能,只匹配一个
exact 属性,精确匹配 path完全相等才算成立,二级路由的时候切记使用
Switch和exact搭配使用
9. 配置二级路由,以home.jsx为例提前创建好两个Demo1.jsx和Demo2.jsx两个页面,去Home.jsx页面去配置
*/}
<Switch>
<Route path='/home' component={Home}></Route>
<Route path='/user' component={User}></Route>
<Route path='/my' component={My}></Route>
{/* 23. 动态路由传参单个,如下 */}
{/* <Route path='/my/:id?' component={My}></Route> */}
{/* 24. 动态路由传参多个,如下 */}
{/* <Route path='/my/:id?/:age?' component={My}></Route> */}
{/* 7. 重定向加上exact好一点 */}
<Redirect from="/" exact to="/home" />
{/* 8. 404配置 可以省略 path="*" */}
<Route path="*" component={NotFound} />
</Switch>
</div>
)
}

export default App

index.js代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// 4. 从第三方路由模块中引入路由模式,作为标签将<App />包裹,回App.js配置一级路由, HashRouter是hash路由的标签多个#,BrowserRouter是history路由标签没有#
// import { HashRouter, BrowserRouter } from 'react-router-dom'
import { HashRouter } from 'react-router-dom'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<HashRouter>
<App />
</HashRouter>
)

  1. 配置二级路由,以home.jsx为例提前创建好两个Demo1.jsx和Demo2.jsx两个页面,去Home.jsx页面去配置
  2. 引入两个子页面,利用Switch标签和Route标签通过path与component和子页面建立连接
  3. 从第三方路由模块中引入Switch标签和Route标签
  4. 利用Switch标签和Route标签通过path与component和子页面建立连接
    二级路由这里与vue的不同,同时React v5版本不能省略一级路由名字 v6版本可以省略
  5. 声明式导航去User.jsx页面和My.jsx页面
    1
    2
    3
    4
    5
    6
    <Switch>
    {/* 写法1 */}
    <Route path='/home/demo1' component={Demo1}></Route>
    {/* 写法2,提成变量写法,由于match当前home对应的路由对象,this.props.match.path拿到Home.jsx的path */}
    <Route path={path + '/demo2'} component={Demo2}></Route>
    </Switch>
    home.jsx
    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
    import React, { Component } from 'react'

    // 11. 引入两个子页面,利用Switch标签和Route标签通过path与component和子页面建立连接
    import Demo1 from './Demo1'
    import Demo2 from './Demo2'
    // 12. 从第三方路由模块中引入Switch标签和Route标签
    import {Switch, Route} from 'react-router-dom'
    class Home extends Component {
    render() {
    // 14. 写法2【在render渲染自执行函数里面写,props】
    // console.log(this.props.match.path) //this.props.match 就是路由中的matched,放的所有层级路由的对象数组
    let path = this.props.match.path
    return (
    <div>
    <h3>Home页面</h3>
    {/*
    13. 利用Switch标签和Route标签通过path与component和子页面建立连接
    二级路由这里与vue的不同,同时React v5版本不能省略一级路由名字 v6版本可以省略
    */}
    {/* 14. 声明式导航去User.jsx页面和My.jsx页面 */}
    <Switch>
    {/* 写法1 */}
    <Route path='/home/demo1' component={Demo1}></Route>
    {/* 写法2,提成变量写法,由于match当前home对应的路由对象,this.props.match.path拿到Home.jsx的path */}
    <Route path={path + '/demo2'} component={Demo2}></Route>
    </Switch>
    </div>
    )
    }
    }

    export default Home
    user.jsx
    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
    49
    import React, { Component } from 'react'

    // 15. 声明式导航需要引入Link标签
    // import { Link } from 'react-router-dom'
    // 17. 编程式导航需要引入一个高阶组件,使用和函数一样,用来获取路由对象的history、location、match等【React@17版本的一个bug,无法获取history这个bug,使用这个withRouter 高阶组件就可以获取history了】
    import { withRouter } from 'react-router-dom'
    class User extends Component {
    // 20. 通过点击事件跳转
    handleClick = () => {
    // this.props.history 全局路由对象,用来做跳转用的,push replace go goback...
    // 21. 字符串写法[传递参数直接在后面拼接参数队列,类似get传参,刷新参数不丢失 有长度限制;不安全]
    // this.props.history.push('/my') // push会变成历史记录可以回退,而replace不可以【浏览器地址栏旁边小箭头,能回退就能点,不能回退就不能点】
    // 22. 对象写法[pathname就是path值]
    // this.props.history.push({
    // pathname: 'my'
    // })
    // 23. 动态路由传参(单个 /:xx?),需要路由支持去App.js配置:xx? [?表示可传可不传,没有?必须传递才能跳转成功]
    // this.props.history.push('/my/123') // 刷新参数不丢失 有长度限制 不安全
    // 26. 动态路由传参(单个 /:xx?),需要路由支持去App.js配置: xx ? [?表示可传可不传,没有 ? 必须传递才能跳转成功]
    // 27. 在落地组件中(My.jsx)通过this.props.match.params接收
    // this.props.history.push('/my/123/456') // 刷新参数不丢失 有长度限制 不安全
    // 28. query传参,通过地址栏中的 home?key=value&key=value传递
    // 29. 在落地组件中(My.jsx)通过this.props.location.search得到
    // this.props.history.push('/my?name=aa&age=22') //刷新参数不丢失 有长度限制 不安全
    // 30. post传参,隐式传参(state),通过地址栏是观察不到的,通过路由对象中的state属性进行数据传递
    // 31. 在落地组件中(My.jsx)通过this.props.location.state得到
    this.props.history.push({ //刷新参数会丢失 没有长度限制 安全比较高
    pathname:'my',
    state:{
    name:'小明',
    age:22
    }
    })
    }
    render() {
    return (
    <div>
    <h3>User页面</h3>
    {/* 16. 声明式导航--->My页面,这里的to就是之前一级路由的path值,也支持传递参数类似get,后面?拼接即可,to可以使用to={};类似get传参,刷新参数不丢失,有长度限制;不安全 */}
    {/* <Link to='/my'>跳转到My页面</Link> */}
    {/* 19. 编程式导航 this.props.history.push */}
    <button onClick={this.handleClick}>点击跳转到My页面</button>
    </div>
    )
    }
    }

    // 18. 使用withRouter高阶组件
    export default withRouter(User)

My.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, { Component } from 'react'

class My extends Component {
// 32. 接收数据
componentDidMount() {
// console.log('动态路由接收参数:', this.props.match.params) // {id: '123', age: '456'}
// note: 处理地址栏参数转对象?工具类、js原生方法、node.js方法之url+queryString、node.js方法之url的解构方法
// console.log('query接收参数:', this.props.location.search) // ?name=aaa&age=22
console.log('post接收参数:', this.props.location.state) // {name: '小明', age: 22}
}
render() {
return (
<div>
<h3>My页面</h3>
</div>
)
}
}

export default My

处理地址栏参数转对象?
工具类、js原生方法、node.js方法之url+queryString、node.js方法之url的解构方法