您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

react路由守卫的实现(路由拦截)

51自学网 2022-05-02 21:35:13
  javascript

react不同于vue,通过在路由里设置meta元字符实现路由拦截。在使用 Vue ,框架提供了路由守卫功能,用来在进入某个路有前进行一些校验工作,如果校验失败,就跳转到 404 或者登陆页面,比如 Vue 中的 beforeEnter 函数:

...router.beforeEach(async(to, from, next) => {    const toPath = to.path;    const fromPath = from.path;})...

react实现路由拦截的基本思路还是利用Route 的render函数。通过判断拦截条件来实现不同的组件的跳转,从而实现拦截。在之前的版本中,React Router 也提供了类似的 onEnter 钩子,但在 React Router 4.0 版本中,取消了这个方法。React Router 4.0 以后采用了声明式的组件,路由即组件,要实现路由守卫功能,就得我们自己去写了。
如果不使用路由守卫,Router 组件是这样子的:

import * as React from 'react';import { HashRouter,Switch,Route,Redirect } from 'react-router-dom'; import Index from "./page/index";import Home from "./page/home";import ErrorPage from "./page/error";import Login from "./page/login"; export const Router = () => (    <HashRouter>        <Switch>            <Route path="/" exact component={Index}/>            <Route path="/login" exact component={Login}/>            <Route path="/home" exact component={Home}/>            <Route path="/404" exact component={ErrorPage}/>            <Redirect to="/404" />        </Switch>    </HashRouter>);

上面的 Router 组件,包含了三个页面:

登陆
主页
404 页面
以及四个路由:
根路由
登陆路由
主页路由
404 路由
其中,根路由和 /home 路由,都定向到了主页路由。
以上是一个基本的路由定义,可以在登陆/主页和 404 页面之间来回跳转,但也有一些问题:
非登陆状态下,可以直接跳转到主页
登陆状态下,也可以输入 /login 路由跳转到登录页
现在,我们想完成这样的功能:
非登陆状态下,无法直接跳转到主页,如果在非登陆状态下进行主页跳转,需要重定向至登陆路由
登陆状态下,无法跳转至登录页,如果在登陆状态下进行登陆页跳转,需要重定向至主页路由
要完成这个功能,有两种方案:
在每个组件中,根据 props 上的 history 对象来进行跳转
进行全局的路由守卫处理

首先在跟目录src下创建一个routerMap.js文件,代码如下:
将 auth 设置为 true,表示该路由需要权限校验。

/** * 定义路由组件,将 auth 设置为 true,表示该路由需要权限校验 */import Admin from "./pages/Admin";import Login from "./pages/Login";import Error from "./pages/Error";export const routerMap = [    {path: "/", name: "admin", component: Admin, auth: true},    {path: "/login", name: "Login", component: Login},    {path: "/error", name: "error", component: Error},];

所有的路由跳转,都交给 FrontendAuth 高阶组件代理完成。下面是 FrontendAuth.js 组件的实现:

/** * 路由守卫校验 */import React, {Component} from "react";import {Route, Redirect} from "react-router-dom";class FrontendAuth extends Component {    // eslint-disable-next-line no-useless-constructor    constructor(props) {        super(props);    }    render() {        const {routerConfig, location} = this.props;        const {pathname} = location;        const isLogin = localStorage.getItem("user");        console.log(pathname, isLogin);        console.log(location);        // 如果该路由不用进行权限校验,登录状态下登陆页除外        // 因为登陆后,无法跳转到登陆页        // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由        const targetRouterConfig = routerConfig.find(            (item) => item.path === pathname        );        console.log(targetRouterConfig);        if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {            const {component} = targetRouterConfig;            return <Route exact path={pathname} component={component}/>;        }        if (isLogin) {            // 如果是登陆状态,想要跳转到登陆,重定向到主页            if (pathname === "/login") {                return <Redirect to="/"/>;            } else {                // 如果路由合法,就跳转到相应的路由                if (targetRouterConfig) {                    return (                        <Route path={pathname} component={targetRouterConfig.component}/>                    );                } else {                    // 如果路由不合法,重定向到 404 页面                    return <Redirect to="/error"/>;                }            }        } else {            // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆            if (targetRouterConfig && targetRouterConfig.auth) {                return <Redirect to="/login"/>;            } else {                // 非登陆状态下,路由不合法时,重定向至 404                return <Redirect to="/error"/>;            }        }    }}export default FrontendAuth;

然后,定义 Router 组件,在App.js中,该组件是经过高阶组件包装后的结果:

import './App.less';import React, {Fragment} from "react";import {Switch} from 'react-router-dom'import FrontendAuth from "./FrontendAuth";import {routerMap} from "./routerMap";function App() {    return (        <Fragment>            {/*只匹配一个,匹配成功就不往下匹配,效率高*/}            <Switch>                <FrontendAuth routerConfig={routerMap}/>            </Switch>        </Fragment>    );}export default App;

测试

到此这篇关于react路由守卫的实现(路由拦截)的文章就介绍到这了,更多相关react路由守卫内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


websocket+Vuex实现一个实时聊天软件
小程序自定义组件全局样式不生效的解决方法
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1