react与vue一样,做SPA就要用到路由功能。我们做WEB端路由,需要用到的是react-router-dom
这个库,它帮助我们实现react路由功能。另外,为了方便起见,代码演示使用react脚手架create-react-app
。关于脚手架的使用可自己搜索。废话不多说,直接撸~
基本使用
首先我修改下脚手架,将/src/index.js
入口文件清空,用来写我们的演示代码,将/public/index.html
模板文件删掉不必要的干扰代码,如下:1
2
3
4
5
6
7
8
9
10
11
12<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
切换到index.js文件,首先引入我们需要的模块:1
2
3import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
前两个不必多说了,而第三个就是我们要用到的路由库,在引入前别忘记下载了:1
npm install --save react-router-dom
我们在react-router-dom
中引入了三个东西,其中,Router是容器,它里面就包含了我们的路由内容,Route是定义真正路由组件的,而Link就是定义切换链接的,类似vue中的router-link
,简单使用如下:
1 | // 首页组件 |
代码中也可以看到,Router
起到容器作用,其本身也是一个组件,需要注意的是,Router下只能有一个根元素,这里即div
。先看Link
,它有一to
属性,很明显代表的是要链接的地址,再看Route
,它的path
属性表明路由的路径,与Link
的to
属性值要对应起来,而component属性指出当前路径所对应的界面(其本质就是对应到一个组件,当链接到当前路径后,展示组件内容)。
怎么样,react路由是不是很简单?其实刚接触时,我有点不习惯这种写法,毕竟受vue影响大了,哈哈~不过当我再写一遍时,我觉得react的路由上手更简单点,至少很直观 ,也许当初我先学react的话,会对vue的路由更不习惯。
嵌套路由
如果说当初刚学vue路由时,我可能不知道怎么定义嵌套路由,但是现在初学react路由时,我自己按着想法,却也把嵌套路由搞出来了,一切也是因为它很直观。因为react路由也是组件形式,那么我在父路由组件里,再写一个子路由不就行了嘛,形式都是一样的,如下: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// xiaoming
const Xiaoming = () => (
<div>
我是小明
</div>
)
// xiaohong
const Xiaohong = () => (
<div>
我是小红
</div>
)
// 用户页组件
const User = () => (
<div>
<h1>这是用户页</h1>
<Router>
<div>
<ul>
<li><Link to="/user/xiaoming">小明</Link></li>
<li><Link to="/user/xiaohong">小红</Link></li>
</ul>
<Route path="/user/xiaoming" component={Xiaoming}></Route>
<Route path="/user/xiaohong" component={Xiaohong}></Route>
</div>
</Router>
</div>
)
如上,我在/user
路由组件里,再写了两个子路由,形式和父路由完全一样,这样就完成了嵌套路由的实现,同理也可继续嵌套下去。而嵌套路由在vue里的实现是配置children,很明显刚学时,我肯定是不知道是要配置children的。不过用这么久vue了,我还是很喜欢vue这个框架的,也习惯了它的设计思想,而react让我看到了不同的设计思想。我相信存在即合理,这两种模式我都喜欢,哈哈又扯多了。
动态路由
react的动态路由匹配与vue的基本类似,也是以冒号开头加参数。我们将上述例子中的user
子路由修改下,我们不明确指向是xiaoming
还是xiaohong
,而是使用动态路由来自动识别,如下:1
2
3
4
5
6
7const Person = () => (
<div>
// ....
</div>
)
<Route path="/user/:name" component={Person} ></Route>
现在,我要求输入不同的name时,浏览器会显示不同的内容。其实关键就是Person
组件该怎么写了,再进一步就是怎么拿到name的值了,这时候我们也会想到react应该会替我们做好这些的。其实,name参数值会被传入到Person组件里,存在props里,而函数定义的组件中,props是以参数形式传进去的。我们可以打印props就会知道name值存在props.match.params
中:1
2
3
4
5const Person = (props) => (
<div>
{props.match.params.name}
</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
28const Person = (props) => {
if(props.match.params.name === 'xiaoming'){
var a = '我是小明'
}else{
var a = '我是小红'
}
return (
<div>{a}</div>
)
}
// 用户页组件
const User = () => (
<div>
<h1>这是用户页</h1>
<Router>
<div>
<ul>
<li><Link to="/user/xiaoming">小明</Link></li>
<li><Link to="/user/xiaohong">小红</Link></li>
</ul>
<Route path="/user/:name" component={Person} ></Route>
</div>
</Router>
</div>
)
上述代码的功能与之前写的一样,只是用动态路由来实现的。当然我这种写法是很 low的,实际开发中应该不会这么写,我只是把过程讲出来,方便理解。
react路由就先讲这么多了,我也实在讲不出花来~