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 相关文章推荐
jquery ajax修改全局变量示例代码
Nov 08 Javascript
javascript中的作用域和上下文使用简要概述
Dec 05 Javascript
JavaScript函数详解
Feb 27 Javascript
ECHO.js 纯javascript轻量级延迟加载的实例代码
May 24 Javascript
javascript和jQuery实现网页实时聊天的ajax长轮询
Jul 20 Javascript
bootstrap table 数据表格行内修改的实现代码
Feb 13 Javascript
vue的安装及element组件的安装方法
Mar 09 Javascript
浅谈React的最大亮点之虚拟DOM
May 29 Javascript
浅谈angularJS2中的界面跳转方法
Aug 31 Javascript
JS数组方法join()用法实例分析
Jan 18 Javascript
基于Element的组件改造的树形选择器(树形下拉框)
Feb 27 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
Mar 23 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 number_format() 函数定义和用法
2012/06/01 PHP
phpmailer在服务器上不能正常发送邮件的解决办法
2014/07/08 PHP
解javascript 混淆加密收藏
2009/01/16 Javascript
JS中如何判断传过来的JSON数据中是否存在某字段
2014/08/18 Javascript
JavaScript字符串常用类使用方法汇总
2015/04/14 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
详解jQuery中的事件
2016/12/14 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
vue2.0 和 animate.css的结合使用
2017/12/12 Javascript
vue v-model实现自定义样式多选与单选功能
2018/07/05 Javascript
JS 验证码功能的三种实现方式
2018/11/26 Javascript
Vue 报错TypeError: this.$set is not a function 的解决方法
2018/12/17 Javascript
详解微信UnionID作用
2019/05/15 Javascript
vue+axios实现post文件下载
2019/09/25 Javascript
[08:54]DOTA2-DPC中国联赛 正赛 Aster vs LBZS 选手采访
2021/03/11 DOTA
Python中类的继承代码实例
2014/10/28 Python
用 Python 爬了爬自己的微信朋友(实例讲解)
2017/08/25 Python
Python集合基本概念与相关操作实例分析
2019/10/30 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
keras 权重保存和权重载入方式
2020/05/21 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
前端canvas水印快速制作(附完整代码)
2019/09/19 HTML / CSS
印度领先的在线时尚商店:Koovs
2016/08/28 全球购物
Meli Melo官网:名媛们钟爱的英国奢侈手包品牌
2017/04/17 全球购物
ROSEFIELD手表荷兰官方网上商店:北欧极简设计女士腕表品牌
2018/01/24 全球购物
新西兰航空中国官网:Air New Zealand China
2018/07/24 全球购物
艺术设计专业个人求职信范文
2013/12/11 职场文书
简历自我评价怎么写好呢?
2014/01/04 职场文书
机械设计毕业生自荐信
2014/02/02 职场文书
广告传媒专业应届生求职信
2014/03/01 职场文书
房产公证书范本
2014/04/10 职场文书
财务务虚会发言材料
2014/10/20 职场文书
优秀教师先进材料
2014/12/16 职场文书
2016年小学教师师德承诺书
2016/03/25 职场文书
《鲁滨逊漂流记》之六读后感(4篇)
2019/09/29 职场文书