React Router 路由
React Router 路由
React Router 开发环境搭建
- 安装React脚手架工具(若之前安装过了可以省略)
1
npm install -g create-react-app
- 创建项目
1
2
3
4
5
6D: //进入D盘
mkdir ReactRouterDemo //创建ReactRouterDemo文件夹
cd ReactRouterDemo //进入文件夹
create-react-app demo01 //用脚手架创建React项目
cd demo01 //等项目创建完成后,进入项目目录
npm start //预览项目,可跳过该步 - 安装 React Router
在终端Ctrl+丶
的项目目录下:1
npm install --save react-router-dom
React Router 使用
创建多个组件作为路由跳转的目标组件
组件目录树: 新建components
文件夹存放组件
1 |
|
Home.js
1 |
|
Analysis.js
1 |
|
Person.js
1 |
|
编写路由组件(React万物皆组件)
新建router
文件夹存放路由组件
1 |
|
重点:
- 上述路由组件中没有状态的变化,因此采用了无状态组件的方式书写。注意引入
React
,凡是用到JSX
语法的都要import React from 'react'
1
2
3
4
5
6
7import React from 'react'
const xxx = () => {
return (
<div>...</div>
)
}
export default xxx - 开头引入
react-router-dom
,否则无法使用路由标签。**NavLink
与Link
相比可以在active
时改变样式,BrowserRouter as Router
设定别名**。
React Router 具体标签属性和使用可以参考官方文档1
2
3import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom'
or
import { BrowserRouter as Router, Route, Link } from 'react-router-dom - 开头引入路由跳转组件
1
2
3import Home from '../components/Home'
import Analysis from '../components/Analysis'
import Person from '../components/Person' - 列表存放路由参数,模拟接收后台请求数据。此处采用遍历路由参数信息列表的方式搭建路由。相较于单独搭建,该方法灵活性更高。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const routeList = [
{
path: "/",
exact: true,
title: "首页",
component: Home,
icon: "iconfont icon-yemian-copy"
},
{
path: "/analysis/",
exact: false,
title: "相关性分析",
component: Analysis,
icon: "iconfont icon-fenxi"
},
{
path: "/person/",
exact: false,
title: "个人档案",
component: Person,
icon: "iconfont icon-icon-text-fn-documentation"
},
] - 遍历路由参数列表,设定
<Route>
1
2
3
4
5
6
7
8
9
10routeList.map((item, index) => {
return (
<Route
exact={item.exact}
path={item.path}
key={index}
component={item.component}
></Route>
)
}) - 遍历路由参数列表,引用
<NavLink>
标签1
2
3
4
5
6
7
8
9
10
11
12
13
14routeList.map((item, index) => (
<div className="subTitle" key={index}>
<i className={item.icon} key={index}></i>
<li className="textItem">
<NavLink
exact={item.exact} //NavLink-exact: if true, 精确匹配active
to={item.path}
key={index}
className="link"
activeClassName="activeLink"
>{item.title}</NavLink>
</li>
</div>
))
注意事项:
- 注意路由的层级关系为
<BrowserRouter>
><Route>
=<Link>
,即<Route>
和<Link>
都必须被包裹在<BrowserRouter>
内使用。1
2
3
4<BrowserRouter>
<Link to=""></Link>
<Route path="" exact component=""></Route>
</BrowserRouter> Link
,NavLink
,Route
常用参数举例:
to: 跳转路径 “string”
path: 路由路径 “string”
exact: 是否精确匹配 (true/false)
component: 目标组件
activeClassName: 链接激活后的样式 “string”
activeStyle: 链接激活后的样式 (css obj)
NavLink - exact: NavLink 中定义的 exact 指确认 active 激活的精确匹配,若不设置可能导致"/""/post/"
两个链接都显示 active 样式<Link to="/"></Link>
<NavLink to="/post/" activeClassName="activeAction" activeStyle={{color:red,}}></NavLink>
<Route path="/post/" exact=true component="Home"></Route>
map()
遍历时要给所遍历的组件加上key
参数,且key
要保证唯一性,此处用key={index}
,但实际应用中往往采用其他办法。<ul><li></li></ul>
无序列表书写格式,不要写错(填坑)
精确匹配 exact
精确匹配从字面上理解,就是你的路径信息要完全匹配成功,才可以实现跳转,匹配一部分是不行的。
例如路由设置了两个跳转路径/
和/post/
,若exact=false
,则路由既可以跳转到/
对应的组件,也可以跳转到/post/
对应的组件。
值得一提的是,我们一般在首页/
的时候采用精确匹配,其余时候不用,当然这也要考虑的实际项目需求,酌情而定。
路由动态传参
参考链接:路由动态传参
通配符传参
在进行路由跳转的过程中,我们可以通过 url 向子组件传递一些参数,这也被称为路由的动态传参。
设置动态传参的步骤如下:
- 在
Route
上设置动态传值 (设置传参的 key 值)1
<Route path="/post/:key" component={Home}></Route>
- 在
Link
上传递值 (value)1
<Link to="/post/123"></Link>
- 在子组件上获取传递的参数
1
2value === this.props.match.params.key
value === 123
注意事项:
- 如果不往 url 里传任何东西,是没办法匹配路由成功的。即若设置了动态传参
:
,则必须要给定一个参数。 - params:传递过来的参数,
key
和value
值。通过this.props.params.xxx
取值,xxx = key
优点:简单快捷,并且在刷新页面的时候,参数不会丢失。
缺点:只能传字符串,并且如果传的值太多的话,url会变得长而丑陋。
如果想传对象的话,可以用JSON.stringify()
,想将其转为字符串,然后另外的页面接收后,用JSON.parse()
转回去。
实例
设置动态路由 & Link传值
1 |
|
子组件接收参数
用了 Ant Design
的标签,标签具体属性可参照官网。
1 |
|
query 传参
<Route>
定义方式同普通路由相同1
<Route path="/post/" component={Home}></Route>
<Link>
定义前需要声明一个对象,保存 url 地址和传递的参数key: value
1
2
3
4
5
6
7
8
9
10const name = {
pathname: "/post/",
query: {
xxx: yyy,
aaa: bbb,
...
}
// query: value (string or obj)
}
<Link to={name}></Link>- 子组件参数获取
1
this.props.location.query
注意事项:
pathname, query
都是固定名称,不能修改,其中pathname
不是驼峰命名,query
表示传递的参数,等价于通配符的key
。- 获取参数时,取的是 url 链接内的
query
属性值,而不是name
。即this.props.location.name
是错误的
优点:优雅,可传对象。
缺点:刷新页面,参数丢失。
实例
1 |
|
子组件接收参数
1 |
|
state 传参
与 query
传参类似:
<Route>
定义方式同普通路由相同1
<Route path="/post/" component={Home}></Route>
<Link>
定义前需要声明一个对象,保存 url 地址和传递的参数key: value
1
2
3
4
5
6
7
8
9
10const name = {
pathname: "/post/",
state: {
xxx: yyy,
aaa: bbb,
...
}
// state: value (string or obj)
}
<Link to={name}></Link>- 子组件参数获取
1
this.props.location.state
重定向
重定向 和 跳转 有一个重要的区别,就是跳转式可以用浏览器的回退按钮返回上一级的,而重定向是不可以的。
标签式重定向
一般用在不是很复杂的业务逻辑中,比如我们进入Index组件,然后Index组件,直接重定向到Home组件。
- 引入
<Redirect>
重定向标签1
import {Redirect} from 'react-router-dom'
- 在
render
函数里使用标签式重定向只能写在1
2
3
4
5
6
7
8
9render() {
return(
<div>
...
<Redirect to="...">
...
</div>
)
}render
函数中,因此无法绑定到一些业务逻辑上,例如一些业务逻辑绑定函数函数体是独立于render
函数之外的,将<Redirect>
标签定义在这类函数体中是不奏效的。因此,我们可以使用另一种编程式的重定向方法,它直接使用JS的语法实现重定向,一般用在业务逻辑比较发杂的场合或者需要多次判断的场合。
编程式重定向
调用方法:直接在函数体中加入以下语句即可
1 |
|
例如在 constructor
构造函数中加入上述代码,即可在组件构造时就进行重定向。
在登陆界面中,我们可以将编程式重定向应用到点击事件判断中,例如当用户名密码与后端一致时,点击确认,重定向到目标路由。这也是标签式重定向无法做到的,具体过程在实战中继续领悟!
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!