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控制框架刷新
Aug 01 Javascript
JavaScript创建类/对象的几种方式概述及实例
May 06 Javascript
脚本合并提升javascript性能示例
Feb 24 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
Apr 12 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
Nov 10 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
Sep 13 Javascript
jQuery EasyUI API 中文帮助文档和扩展实例
Aug 01 Javascript
JS 实现导航菜单中的二级下拉菜单的几种方式
Oct 31 Javascript
AngularJs验证重复密码的方法(两种)
Nov 25 Javascript
Vue2路由动画效果的实现代码
Jul 10 Javascript
微信小程序数据存储与取值详解
Jan 30 Javascript
微信小程序页面间跳转传参方式总结
Jun 13 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 出现乱码的解决方法
2008/08/08 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP PDOStatement::debugDumpParams讲解
2019/01/30 PHP
PHP PDOStatement::execute讲解
2019/01/31 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
用JavaScript脚本实现Web页面信息交互
2006/10/11 Javascript
科讯商业版中用到的ajax空间与分页函数
2007/09/02 Javascript
比较简单实用的使用正则三种版本的js去空格处理方法
2007/11/18 Javascript
ko knockoutjs动态属性绑定技巧应用
2012/11/14 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
JavaScript 中使用 Generator的方法
2017/12/29 Javascript
angular 实时监听input框value值的变化触发函数方法
2018/08/31 Javascript
JavaScript实现页面中录音功能的方法
2019/06/04 Javascript
jQuery 查找元素操作实例小结
2019/10/02 jQuery
针对Vue路由history模式下Nginx后台配置操作
2020/10/22 Javascript
python3模拟百度登录并实现百度贴吧签到示例分享(百度贴吧自动签到)
2014/02/24 Python
用python找出那些被“标记”的照片
2017/04/20 Python
python交互式图形编程实例(二)
2017/11/17 Python
用Python3创建httpServer的简单方法
2018/06/04 Python
python将pandas datarame保存为txt文件的实例
2019/02/12 Python
使用Python实现将list中的每一项的首字母大写
2019/06/11 Python
Python socket实现的文件下载器功能示例
2019/11/15 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
python Matplotlib数据可视化(2):详解三大容器对象与常用设置
2020/09/30 Python
纯HTML+CSS3制作导航菜单(附源码)
2013/04/24 HTML / CSS
CK巴西官方网站:Calvin Klein巴西
2019/07/19 全球购物
如何将整数int转换成字串String
2014/03/21 面试题
致短跑运动员广播稿
2014/01/09 职场文书
学生会主席就职演讲稿
2014/01/14 职场文书
优秀管理者获奖感言
2014/02/17 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
捐款感谢信
2015/01/20 职场文书
小升初自荐信怎么写
2015/03/26 职场文书
vue如何使用模拟的json数据查看效果
2022/03/31 Vue.js