react router4+redux实现路由权限控制的方法


Posted in Javascript onMay 03, 2018

总体概述

一个完善的路由系统应该是这样子的,当链接到的组件是需要登录后才能查看,要能够跳转到登录页,然后登录成功后又跳回来之前想访问的页面。这里主要是用一个权限控制类来定义路由路由信息,同时用redux把登录成功后要访问的路由地址给保存起来,登录成功时看redux里面有没有存地址,如果没有存地址就跳转到默认路由地址。

路由权限控制类

在这个方法里面,通过sessionStorage判断是否登录了,如果没有登录,就保存一下当前想要跳转的路由到redux里面。然后跳转到我们登录页。

import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { setLoginRedirectUrl } from '../actions/loginAction'

class AuthorizedRoute extends React.Component {
  render() {
    const { component: Component, ...rest } = this.props
    const isLogged = sessionStorage.getItem("userName") != null ? true : false;
    if(!isLogged) {
      setLoginRedirectUrl(this.props.location.pathname);
    }
    return (
        <Route {...rest} render={props => {
          return isLogged
              ? <Component {...props} />
              : <Redirect to="/login" />
        }} />
    )
  }
}

export default AuthorizedRoute

路由定义信息

路由信息也很简单。只是对需要登录后才能查看的路由用AuthorizedRoute定义。

import React from 'react'
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom'

import Layout from '../pages/layout/Layout'
import Login from '../pages/login/Login'
import AuthorizedRoute from './AuthorizedRoute'
import NoFound from '../pages/noFound/NoFound'
import Home from '../pages/home/Home'
import Order from '../pages/Order/Order'
import WorkOrder from '../pages/Order/WorkOrder'

export const Router = () => (
    <BrowserRouter>
      <div>
        <Switch>
          <Route path="/login" component={Login} />
          <Redirect from="/" exact to="/login"/>{/*注意redirect转向的地址要先定义好路由*/}
          <AuthorizedRoute path="/layout" component={Layout} />
          <Route component={NoFound}/>
        </Switch>
      </div>
    </BrowserRouter>
)

登录页

就是把存在redux里面的地址给取出来,登录成功后就跳转过去,如果没有就跳转到默认页面,我这里是默认跳到主页。因为用了antd的表单,代码有点长,只需要看连接redux那两句和handleSubmit里面的内容。

import React from 'react'
import './Login.css'
import { login } from '../../mock/mock'
import { Form, Icon, Input, Button, Checkbox } from 'antd';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux'
const FormItem = Form.Item;

class NormalLoginForm extends React.Component {
  constructor(props) {
    super(props);
    this.isLogging = false;
  }
  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        this.isLogging = true;
        login(values).then(() => {
          this.isLogging = false;
          let toPath = this.props.toPath === '' ? '/layout/home' : this.props.toPath
          this.props.history.push(toPath);
        })
      }
    });
  }
  render() {
    const { getFieldDecorator } = this.props.form;
    return (
        <Form onSubmit={this.handleSubmit.bind(this)} className="login-form">
          <FormItem>
            {getFieldDecorator('userName', {
              rules: [{ required: true, message: 'Please input your username!' }],
            })(
                <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />
            )}
          </FormItem>
          <FormItem>
            {getFieldDecorator('password', {
              rules: [{ required: true, message: 'Please input your Password!' }],
            })(
                <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
            )}
          </FormItem>
          <FormItem>
            {getFieldDecorator('remember', {
              valuePropName: 'checked',
              initialValue: true,
            })(
                <Checkbox>Remember me</Checkbox>
            )}
            <a className="login-form-forgot" href="">Forgot password</a>
            <Button type="primary" htmlType="submit" className="login-form-button"
                loading={this.isLogging ? true : false}>
              {this.isLogging ? 'Loging' : 'Login'}
            </Button>
            Or <a href="">register now!</a>
          </FormItem>
        </Form>
    );
  }
}

const WrappedNormalLoginForm = Form.create()(NormalLoginForm);

const loginState = ({ loginState }) => ({
  toPath: loginState.toPath
})

export default withRouter(connect(
    loginState
)(WrappedNormalLoginForm))

顺便说一下这里redux的使用吧。我暂时只会基本使用方法:定义reducer,定义actions,创建store,然后在需要使用redux的变量时候去connect一下redux,需要dispatch改变变量时,就直接把actions里面的方法引入,直接调用就可以啦。为了让actions和reducer里面的事件名称对的上,怕打错字和便于后面修改吧,我建了个actionsEvent.js来存放事件名称。
reducer:

import * as ActionEvent from '../constants/actionsEvent'

const initialState = {
  toPath: ''
}

const loginRedirectPath = (state = initialState, action) => {
  if(action.type === ActionEvent.Login_Redirect_Event) {
    return Object.assign({}, state, {
      toPath: action.toPath
    })
  }
  return state;
}

export default loginRedirectPath

actions:

import store from '../store'
import * as ActionEvent from '../constants/actionsEvent'

export const setLoginRedirectUrl = (toPath) => {
  return store.dispatch({
         type: ActionEvent.Login_Redirect_Event,
        toPath: toPath
       })
}

创建store

import { createStore, combineReducers } from 'redux'
import loginReducer from './reducer/loginReducer'

const reducers = combineReducers({
  loginState: loginReducer //这里的属性名loginState对应于connect取出来的属性名
})

const store = createStore(reducers)

export default store

差点忘记说了,路由控制类AuthorizedRoute参考了https://codepen.io/bradwestfall/project/editor/XWNWge?preview_height=50&open_file=src/app.js 这里的代码。感觉这份代码挺不错的,我一开始不会做就是看懂它才有点思路。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript import css实例代码
Jul 18 Javascript
使用Js让Html中特殊字符不被转义
Nov 05 Javascript
iframe父页面获取子页面参数的方法
Feb 21 Javascript
jquery 实现两级导航菜单附效果图
Mar 07 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
Sep 04 Javascript
javascript实现汉字转拼音代码分享
Apr 20 Javascript
JavaScript函数的调用以及参数传递
Oct 21 Javascript
JavaScript判断变量是否为数组的方法(Array)
Feb 24 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
May 31 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 Javascript
JavaScript中while循环的基础使用教程
Aug 11 Javascript
你不知道的 TypeScript 高级类型(小结)
Aug 28 Javascript
vue.js学习笔记之v-bind和v-on解析
May 03 #Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 #jQuery
详解VueJs中的V-bind指令
May 03 #Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
May 02 #Javascript
用ES6写全屏滚动插件的示例代码
May 02 #Javascript
详解Vue中watch的高级用法
May 02 #Javascript
Vue.js中关于侦听器(watch)的高级用法示例
May 02 #Javascript
You might like
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
php的mkdir()函数创建文件夹比较安全的权限设置方法
2014/07/28 PHP
基于ThinkPHP实现批量删除
2015/12/18 PHP
php+javascript实现的动态显示服务器运行程序进度条功能示例
2017/08/07 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
jquery 获取json数据实现代码
2009/04/27 Javascript
基于jquery的时间段实现代码
2012/08/02 Javascript
Document.location.href和.replace的区别示例介绍
2014/03/04 Javascript
JS实现黑客帝国文字下落效果
2015/09/01 Javascript
JavaScript类型系统之Object详解
2016/01/07 Javascript
逻辑表达式中与或非的用法详解
2016/06/06 Javascript
省市区三级联动jquery实现代码
2020/04/15 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
2018/01/22 Javascript
jQuery 导航自动跟随滚动的实现代码
2018/05/30 jQuery
vue操作动画的记录animate.css实例代码
2019/04/26 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
解决VUE双向绑定失效的问题
2019/10/29 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
详解Python 装饰器执行顺序迷思
2018/08/08 Python
Python中的random.uniform()函数教程与实例解析
2019/03/02 Python
python文件操作的简单方法总结
2019/11/07 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
python生成大写32位uuid代码
2020/03/03 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
2020/06/28 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
2020/08/27 Python
Python:__eq__和__str__函数的使用示例
2020/09/26 Python
10个python爬虫入门实例(小结)
2020/11/01 Python
JAVA中的关键字有什么特点
2014/03/07 面试题
元旦寄语大全
2014/04/10 职场文书
机关作风建设整改方案
2014/10/27 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
Mysql实现简易版搜索引擎的示例代码
2021/08/30 MySQL
Python 数据可视化之Matplotlib详解
2021/11/02 Python
Python Flask搭建yolov3目标检测系统详解流程
2021/11/07 Python