react路由守卫

react没有vue那样的路由钩子beforeEach,实现登陆验证。

实现效果:如果没有登陆,就跳转到登陆界面,如果登陆过浏览器存有登陆信息就跳转到所输入的路由界面,如果该路由不存在则跳到404页面。

router文件夹下新建index.jsx和auth.jsx

index.jsx  把页面导入进来,配置路由,传入到auth中,auth遍历所有路由。

import React, { Component } from 'react';
import {HashRouter as Router, Switch } from 'react-router-dom'
import Auth from './auth'
import Home from '../pages/Home'
import Login from '../pages/Login'
import NotFound from '../pages/NotFound'

export default class RouterMap extends React.Component {
  constructor(props,context){
    super(props,context)
  }

  render() {
    const routerConfig = [
        {path:'/',component:Home,auth:true},
        {path:'/home',component:Home,auth:true},
        {path:'/login',component:Login},
        {path:'/404',component:NotFound}
    ];
    return (
      <Router history={this.props.history}>
        <Switch>
          <Auth config={routerConfig} />
        </Switch>
      </Router>
    )
  }

}

auth.jsx

import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom'
import App from '../pages/App'
import Login from '../pages/Login'
import NotFound from '../pages/NotFound'

export default class Auth extends React.Component{
      render(){
          const { location,config } = this.props;
          const { pathname } = location;
          const isLogin = localStorage.getItem('USERINFO')
          // console.log(isLogin);
          // console.log(store.getState());
          // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由
          const targetRouterConfig = config.find((v) => v.path === pathname);
          if(targetRouterConfig && !targetRouterConfig.auth && !isLogin){
              const { component } = targetRouterConfig;
              return <Route exact path={pathname} component={component} />
          }

          if(isLogin){ 
              // 如果是登陆状态,想要跳转到登陆
              if(pathname === '/login'){
                  return <Route exact path='/login' component={Login}/>
              }else{
                  // 如果路由合法,就跳转到相应的路由
                  if(targetRouterConfig&&pathname!=='/404'){ //这里用app包裹组件是因为app里有除登录页和404页的其他页面公用的头部组件和侧边菜单组件
                      return <App><Route path={pathname} component={targetRouterConfig.component} /></App>
                  }else if(pathname === '/404'){
                      return <Route exact path='/404' component={NotFound}/>
                  }else{
                    // 如果路由不合法,重定向到 404 页面
                     return <Redirect to='/404' />
                  }
              }
          }else{
            // 非登陆状态下,重定向到登陆页
            return <Redirect to='/login' />
          }
      }
  }

App.jsx 父组件

import React, { Component } from 'react';
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import Header from '../components/header/index'
import Menu from '../components/menu/index'
import * as userinfoActions from '../store/userinfo/action'

class App extends React.Component {

  render() {
    return (
      <div className="App">
        <Header title="NINGMENG 后台管理系统" username={this.props.userInfo.username}/> // 这个是头部公用组件
        <Menu /> // 侧栏菜单公用组件
        {this.props.children}
      </div>
    )
  }
  componentDidMount() {
    let userInfo = JSON.parse(localStorage.getItem('USERINFO'))
      this.props.userInfoActions.saveUserInfo(userInfo) // 在登陆页面的时候如果登陆成功就把登陆信息存到localStorage里面,跳到首页之后把用户信息存到redux
  }
}

// 下面的是redux的写法
function mapStateToProps(state){ return { userInfo: state.userInfo } } function mapDispatchToProps(dispatch){ return { userInfoActions: bindActionCreators(userinfoActions, dispatch) } } export default connect( mapStateToProps, mapDispatchToProps )(App)

 更多代码见 https://github.com/leitingting08/react-app

posted @ 2019-01-21 15:57  c-137Summer  阅读(883)  评论(0编辑  收藏  举报