目前流行的前端框架大都构建的是SPA(单页面应用程序),也就是只有一个HTML页面的应用程序。前端路由的出现,就是为了实现在单页面上对多页面内容的管理。前端路由可以让用户从一个页面导航跳转到另一个页面,但HTML页面本身并没有跳转,仅仅是页面内容发生了变化。
在React中,路由是一套映射规则,是URL路径与组件的对应关系。配置路由就是配置路径和组件的对应关系。
① 安装路由的依赖包:npm i react-router-dom
② 导入路由的三个核心组件: Router(BrowserRouter 和 HashRouter )、Route、Link
③ 使用Router 组件包裹整个应用(包裹最外层的元素)
④ 使用Link组件作为路由跳转导航菜单(路由入口)
⑤ 使用Route 组件配置路由规则以及要展示的组件(路由出口)
/*
react-router-dom 的基本使用:
1、 安装: npm i react-router-dom
*/
// 2、 导入组件:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
// 要展示的组件
const First = () => 页面一的内容
// 3、 使用Router组件包裹整个应用
const App = () => (
React路由基础
{/* 4、 指定路由入口,即要跳转的路由地址 */}
页面一
{/* 5、 指定路由出口,即要匹配的路由地址和要展示的组件 */}
)
ReactDOM.render( , document.getElementById('root'))
该组件包裹整个项目应用,一个React应用只需要在最外层包裹一次。Router有两种常用的类型:HashRouter 和 BrowserRouter(推荐) 。我们在导入组件时,可以选择导入哪种类型的Router。
HashRouter 是基于URL的哈希值实现的,当路由跳转时,url中会带有 #
这个字符(localhost:3000/#/first)。
BrowserRouter 是基于H5的 history API 实现的,url地址中不带有 #
(localhost:3000/#/first)。
该组件用来指定导航链接,用to属性指定要跳转的路由地址,即url地址中的pathname。在页面渲染时,会被渲染成 a 标签。
该组件用来指定匹配的路由地址和对应要展示的组件,path属性指定匹配的路由地址,component属性指定要展示的组件。Route 组件写在页面的哪个位置,要展示的组件就会渲染到哪个位置。
如果想要给页面设置显示默认内容,我们可以通过设置 path="/" 的方式,来设置默认路由实现。默认路由在进入页面时就会被匹配到,然后渲染显示对应组件内容。
在默认情况下,React路由的匹配规则是模糊匹配的,即只要Link组件的to属性指定的路由地址。以Route组件的path属性规定的路由地址开头,就会匹配成功,然后再页面中渲染显示出来。
path(Route组件的path属性) | 能匹配的pathname(Link组件的to属性) |
---|---|
/ | 所有的pathname |
/first | /first或/first/a或/first/a/b等等 |
很显然模糊匹配并不能完全符合我们的需求,所以我们可以通过给Route组件添加 exact
属性,使匹配规则变为精确匹配,只有 path 与 pathname 完全匹配时,才会匹配成功,渲染展示组件内容。
/* 默认路由,添加 exact 属性,就会让当前路由变为精确匹配 */
/* 此时只匹配pathname="/" 这一种情况 */
/* 默认为模糊匹配 */
① 当点击我们写好的 Link 标签时,就会根据 to 属性,修改浏览器地址栏中的 url 。
② React路由监听到地址栏url的变化。
③ 路由内部遍历所有的 Route 组件,将 path 与 pathname 进行匹配。
④ 当匹配到对应的 Route 组件后,就渲染对应的组件到页面中。
React的页面跳转除了可以通过路由的Link组件实现,还可以通过路由提供的 history 对象实现。在组件中访问history 对象,需要通过props来获取到history 对象,history 对象中存有浏览器历史记录的相关信息。这种通过调用对象方法实现的跳转,称为编程式导航。
常用方法有两个:
该方法是跳转到某个页面,参数 path 表示要跳转页面的路由地址。
该方法用来以浏览器历史记录为标准前进或后退页面,参数 n 表示前进或后退页面的数量,负数表示后退,正数表示前进。
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
class Login extends React.Component {
handleLogin = () => {
// 使用编程式导航实现路由跳转
this.props.history.push('/home')
}
render() {
return (
登录页面:
)
}
}
const Home = props => {
const handleBack = () => {
// go(-1) 表示返回上一个页面
props.history.go(-1)
}
return (
我是后台首页
)
}
const App = () => (
编程式导航:
去登录页面
)