React-class——路由(简介、基本使用、路由组件懒加载、路由传参、嵌套路由、路由认证)

目录

路由

(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",

(1)简介

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操作触发事件控制路由。

(2)基本使用

  • 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标签

  • 6、使用步骤

    第一步,规则定义:router.js文件配置路由
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 (
        <div>
          {/*路由容器,所有的Route 与Link 组件都要放置其内部*/}
          <Router>
            {/*这里需要一个容器,内部存放多个路由*/}
            <div> 
                {/*方法1:复杂路由放前边,辅助精确匹配*/}
               <Route path="/news" component={NewsPage}></Route>
                {/*方法2:为根路由添加精确匹配*/}
               <Route path="/" exact component={IndexPage}></Route>
              
            </div>
          </Router>
        </div>
    );
  }
}
export default MyRouter;

第二步,页面导入 :App.js文件导入使用路由

import React from 'react';
import MyRouter from "../router/router";

class App extends React.Component{
  render(){
    return (
      <div>
          {/*使用路由规则*/}
          <MyRouter></MyRouter>
      </div>
    )
  }
}

export default App;

第三步,创建链接标签 :IndexPage.js

import {Link} from "react-router-dom";
import MyRouter from "../router/router";

class IndexPage extends React.Component {
    render() {
        return (
            <div>
               首页
               <Link to="/">首面</Link>
               <Link to="/news">新闻页面</Link>
            </div>
          );
    }
  
}
export default IndexPage;

另一种,组件规则的定义方式,参考官网:https://reactrouter.com/web/guides/quick-start

<Router>
    <Switch>
        <Route path="/about">
            <About />
        </Route>
        <Route path="/users">
            <Users />
        </Route>
        {/*为根路由添加精确匹配*/}
        <Route path="/" exact>
            <Home />
        </Route>
    </Switch>
    </div>
</Router>

(3)路由组件懒加载

react-loadable 实现router.js文件路由组件懒加载
cnpm i -S react-loadable

loadable.js:

/*路由懒加载(异步组件)*/
import React from 'react';
import Loadable from 'react-loadable';
 
//通用的过场组件
const LoadingComponent =(props)=>{
    return (
        <div>loading...</div>
    )
}
 
//过场组件默认采用通用的,若传入了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'))

//……定义/导出 路由规则

(4)路由传参

跳转:声明式导航、编程式导航

不能写a标签,因为a标签的话会刷新整个页面。声明式导航、编程式导航

1.动态路由传参,router.js

<Route path="/news/detail/:id/:title" component={NewsDetailPage}></Route>

在Link 的to 属性中传递,indexPage.js

//传递参数值
<Link to="/news/detail/1/新闻详情页1">新闻详情页1</Link>

//在组件内部获取参数
this.props.match.params.id

以上这种写法有局限性,因为在路由后面我们不确定参数个数或丢失参数时,无法匹配任何组件;需要额外定义一个组件进行提示。

2.编程式跳转传参(导航式跳转)

  • 利用导航式路由进行query 传参,注意使用BrowerRouter 模式,防止浏览器缓存

    第一步,路由规则定义,router.js

//声明要传递的参数
<Route path="/news/detail" component={NewsDetailPage}></Route>

第二步,通过事件处理函数进行导航,事件处理函数中**this 的指向**,必须为**某个路由对应的组件对象**

<li onClick={()=>{
       this.props.history.push({
            pathname:"/news/detail",
            //search:"?id=1&title=新闻详情2",
            query:{
                  id:1,
                  title:'新闻详情2'
            }
        })
  }}>新闻详情2</li>
  
  //目标页面获取参数
  this.props.location.query.id  
  this.props.location.search    //不会丢失参数,但因为是字符串类型,直接使用不方便

路由传参方式**【总结】**:

1. 动态路由规则定义params 传参:在组件内部使用 this.props.match.params.id 获取参数
2. 导航式路由query 传参:在组件内部使用 this.props.location.query.id 获取参数

(5)嵌套路由

- 在父路由组件中,通过Switch匹配子组件:

<div>
    <button onClick={this.returnPage.bind(this)}>返回</button>
    商品详情页
    
        <ul>
            <li>
                <Link to="/goods/item">商品</Link>
            </li>
            <li>
                <Link to="/goods/review">评价</Link>
            </li>
            <li>
                <Link to="/goods/detail">详情</Link>
            </li>
            <li>
                <Link to="/goods/recommend">推荐</Link>
            </li>
        </ul>

        <Switch>
            <Route path="/goods/item" component={ItemPage}></Route>
            <Route path="/goods/review" component={ReviewPage}></Route>
            <Route path="/goods/detail" component={DetailPage}></Route>
            <Route path="/goods/recommend" component={RecommendPage}></Route>
        </Switch>
    
</div>

(6)路由认证

模拟路由守卫实现原理,自己制作鉴权认证组件

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 (<BrowserRouter>
       <Switch>
        <Route path="/home" component={Loadable(() =>import("../views/home/index.js"))}/>      
        <Route path="/login" component={Loadable(()=>import("../views/login/index.js"))}/>       
        <Route path="/register" component={Loadable(()=>import("../views/register/index.js"))}/>
        <OAuth path="/car" component={Loadable(() => import("../views/car/index.js"))}/>
        <OAuth path="/info" component={Loadable(() => import("../views/info/index.js"))}/>
        <Route path='/'component={Loadable(() => import("../views/home/index.js"))}/>        
       </Switch>
     </BrowserRouter>)
   }
}
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 <Redirect to="/login"></Redirect> }
        else {
            return <Route path={this.props.path} component={this.props.component}></Route>
        }
    }
}
export default oAuth

猜你喜欢

转载自blog.csdn.net/qq_52301431/article/details/127282176