React笔记(九)
前言
eg:代表代码对照 若文章有误,欢迎读者留言反馈路由 React-Router V5版本
提前创建pages文件夹里面放几个页面
- 根组件一般使用函数组件,也可以使用类组件
- 安装插件学习v5.3.0版本路由 npm i -S react-router-dom@5.3.0
- App.js需要去入口文件,配置路由模式
- 引入页面
- 从第三方路由模块中引入Route路由对象当标签使用,Switch标签和Redirect重定向标签
- 使用标签配置一级路由【地址栏输入路径默认与这里的path做正则匹配,包含这里path就符合,不加switch会每个都匹配】
- 通过route这个标签绑定两个属性,建立path 和 component的一个映射关系
- Switch 指定我们路由匹配规则,提高性能,只匹配一个
- exact 属性,精确匹配 path完全相等才算成立,二级路由的时候切记使用
- Switch和exact搭配使用
- 重定向加上exact好一点
- 404配置 可以省略 path=”*”
- 配置二级路由,以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
43import 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
13import 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>
)
- 配置二级路由,以home.jsx为例提前创建好两个Demo1.jsx和Demo2.jsx两个页面,去Home.jsx页面去配置
- 引入两个子页面,利用Switch标签和Route标签通过path与component和子页面建立连接
- 从第三方路由模块中引入Switch标签和Route标签
- 利用Switch标签和Route标签通过path与component和子页面建立连接
二级路由这里与vue的不同,同时React v5版本不能省略一级路由名字 v6版本可以省略 - 声明式导航去User.jsx页面和My.jsx页面home.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>user.jsx1
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
32import 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 Home1
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
49import 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.jsx1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import 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的解构方法