当前位置: 移动技术网 > IT编程>开发语言>JavaScript > react router4+redux实现路由权限控制的方法

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

2018年05月11日  | 移动技术网IT编程  | 我要评论

总体概述

一个完善的路由系统应该是这样子的,当链接到的组件是需要登录后才能查看,要能够跳转到登录页,然后登录成功后又跳回来之前想访问的页面。这里主要是用一个权限控制类来定义路由路由信息,同时用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 这里的代码。感觉这份代码挺不错的,我一开始不会做就是看懂它才有点思路。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网