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 相关文章推荐
js查找父节点的简单方法
Jun 28 Javascript
js+JQuery返回顶部功能如何实现
Dec 03 Javascript
JS解决url传值出现中文乱码的另类办法
Apr 08 Javascript
JavaScript实现简单图片滚动附源码下载
Jun 17 Javascript
node.js中的querystring.stringify方法使用说明
Dec 10 Javascript
javascript框架设计之种子模块
Jun 23 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
Jun 07 Javascript
JS图片等比例缩放方法完整示例
Aug 03 Javascript
jQuery插件zTree实现的多选树效果示例
Mar 08 Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
May 05 jQuery
小程序登录态管理的方法示例
Nov 13 Javascript
Vue Elenent实现表格相同数据列合并
Nov 30 Vue.js
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(1)
2006/10/09 PHP
PHP函数preg_match_all正则表达式的基本使用详细解析
2013/08/31 PHP
php中用memcached实现页面防刷新功能
2014/08/19 PHP
php 模拟 asp.net webFrom 按钮提交事件实例
2014/10/13 PHP
PHP基于工厂模式实现的计算器实例
2015/07/16 PHP
用jquery实现学校的校历(asp.net+jquery ui 1.72)
2010/01/01 Javascript
对xmlHttp对象方法和属性的理解
2011/01/17 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
jsPDF生成pdf后在网页展示实例
2014/01/16 Javascript
基于jquery实现表格内容筛选功能实例解析
2016/05/09 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
微信小程序技巧之show内容展示,上传文件编码问题
2017/01/23 Javascript
微信小程序 扎金花简单实例
2017/02/21 Javascript
Vue iview-admin框架二级菜单改为三级菜单的方法
2018/07/03 Javascript
layui实现点击按钮给table添加一行
2018/08/10 Javascript
在Vant的基础上封装下拉日期控件的代码示例
2018/12/05 Javascript
react同构实践之实现自己的同构模板
2019/03/13 Javascript
JavaScript模块管理的简单实现方式详解
2019/06/15 Javascript
Layui弹框中数据表格中可双击选择一条数据的实现
2020/05/06 Javascript
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
[01:09]DOTA2次级职业联赛 - ishow.HMM战队宣传片
2014/12/01 DOTA
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python使用剪切板的方法
2017/06/06 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
python 文件查找及内容匹配方法
2018/10/25 Python
在Python中使用MySQL--PyMySQL的基本使用方法
2019/11/19 Python
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
2014年3.15团委活动总结
2014/03/16 职场文书
合伙协议书
2014/04/23 职场文书
低碳生活的宣传标语
2014/06/23 职场文书
乡镇爱国卫生月活动总结
2014/06/25 职场文书
企业党建工作总结2015
2015/05/26 职场文书
黄埔军校观后感
2015/06/10 职场文书
Tomcat用户管理的优化配置详解
2022/03/31 Servers