目录
路由
(1)简介
(2)基本使用
1、下载 react-router-dom库
2、相关组件使用
3、Route:路由规则,用于匹配路由组件
4、exact : Route属性,精确匹配路由
5、Link:导航链接,相当于a标签
6、使用步骤
(3)路由组件懒加载
(4)路由传参
1.动态路由传参,router.js
2.编程式跳转传参(导航式跳转)
(5)嵌套路由
(6)路由认证
以下讲的都是这个版本: "react-router-dom": "^5.0.2",
React构建的是单页面应用,使用路由实现页面跳转。通过管理 URL,实现组件的切换和状态的变化
官网:Home v6.4.2 | React Router
react-router: 实现了路由的核心功能,提供了router的核心api。如Router、Route、Switch等,但没有提供有关dom操作进行路由跳转的api;
react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签。路由模式分为:BrowserRouter(history)(不带#号)和HashRouter(带#号)。原理--history使用pushState和popstate事件构建路由;hash使用window.location.hash和hashchange事件构建路由。可以通过dom操作触发事件控制路由。
1、下载
react-route r-dom
库cnpm i react-router-dom --save
2、相关组件使用
BrowserRouter/HashRouter:
是一个路由容器,所有的路由组件(Route)、导航链接(Link)都要放置在该组件内部。
import 导入时使用as可以设置一个别名。
BrowserRouter没有#,HashRouter有#。
Switch:路由块,只要匹配到一个地址不往下匹配,相当于for循环里面的break
3、Route:路由规则,用于匹配路由组件
4、exact : Route属性,精确匹配路由
5、Link:导航链接,相当于a标签
第一步,规则定义:router.js文件配置路由6、使用步骤
import React from 'react';
import {HashRouter as Router, Route} from "react-router-dom";
import IndexPage from "./pages/IndexPage";
import NewsPage from "./pages/NewsPage";
class MyRouter extends React.Component {
render() {
return (
{/*路由容器,所有的Route 与Link 组件都要放置其内部*/}
{/*这里需要一个容器,内部存放多个路由*/}
{/*方法1:复杂路由放前边,辅助精确匹配*/}
{/*方法2:为根路由添加精确匹配*/}
);
}
}
export default MyRouter;
第二步,页面导入 :App.js文件导入使用路由
import React from 'react';
import MyRouter from "../router/router";
class App extends React.Component{
render(){
return (
{/*使用路由规则*/}
)
}
}
export default App;
第三步,创建链接标签 :IndexPage.js
import {Link} from "react-router-dom";
import MyRouter from "../router/router";
class IndexPage extends React.Component {
render() {
return (
首页
首面
新闻页面
);
}
}
export default IndexPage;
另一种,组件规则的定义方式,参考官网:https://reactrouter.com/web/guides/quick-start
{/*为根路由添加精确匹配*/}
react-loadable 实现router.js文件路由组件懒加载
cnpm i -S react-loadable
loadable.js:
/*路由懒加载(异步组件)*/
import React from 'react';
import Loadable from 'react-loadable';
//通用的过场组件
const LoadingComponent =(props)=>{
return (
loading...
)
}
//过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
export default (loader,loading = LoadingComponent)=>{
return Loadable({
loader,
loading
});
}
router.js(严格模式下会报出红色警告信息)
import React from "react";
import {BrowserRouter as Router,Switch,Link,Route} from "react-router-dom";
import loadable from "./js/loadable";
// 异步加载组件
const Welcom = loadable(() => import('../pages/Home'))
const UserManage = loadable(() => import('../pages/UserManage'))
const Menus = loadable(() => import('../components/Menu/Menu'))
//……定义/导出 路由规则
跳转:声明式导航、编程式导航
不能写a标签,因为a标签的话会刷新整个页面。声明式导航、编程式导航
在Link 的to 属性中传递,indexPage.js
//传递参数值
新闻详情页1
//在组件内部获取参数
this.props.match.params.id
以上这种写法有局限性,因为在路由后面我们不确定参数个数或丢失参数时,无法匹配任何组件;需要额外定义一个组件进行提示。
利用导航式路由进行query 传参,注意使用BrowerRouter 模式,防止浏览器缓存
第一步,路由规则定义,router.js
//声明要传递的参数
第二步,通过事件处理函数进行导航,事件处理函数中**this 的指向**,必须为**某个路由对应的组件对象**
{
this.props.history.push({
pathname:"/news/detail",
//search:"?id=1&title=新闻详情2",
query:{
id:1,
title:'新闻详情2'
}
})
}}>新闻详情2
//目标页面获取参数
this.props.location.query.id
this.props.location.search //不会丢失参数,但因为是字符串类型,直接使用不方便
路由传参方式**【总结】**:
1. 动态路由规则定义params 传参:在组件内部使用 this.props.match.params.id 获取参数
2. 导航式路由query 传参:在组件内部使用 this.props.location.query.id 获取参数
- 在父路由组件中,通过Switch匹配子组件:
商品详情页
-
商品
-
评价
-
详情
-
推荐
模拟路由守卫实现原理,自己制作鉴权认证组件
Redirect组件是一种重定向组件 我们可以利用它来实现路由的分流:
用户访问url=>Redirect分流=>
(1.有权限:去目标路由)
(2.没有权限:重定向去登录路由接口)
router.js
import React from "react"
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Loadable from "../loadable"
import OAuth from "./oAuth.jsx"
class Router extends React.Component {
render() {
return (
import("../views/home/index.js"))}/>
import("../views/login/index.js"))}/>
import("../views/register/index.js"))}/>
import("../views/car/index.js"))}/>
import("../views/info/index.js"))}/>
import("../views/home/index.js"))}/>
)
}
}
export default Router
oAuth.js
import React from "react"
import { Redirect, Switch, Route } from "react-router-dom"
import loadable from "../loadable"
class oAuth extends React.Component {
render() {
console.log(this.props)
let flag = false//假数据 代表是否登录过,真实项目是取缓存
if (!flag) { return }
else {
return
}
}
}
export default oAuth