欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-10 11:38:30
总体概述 一个完善的路由系统应该是这样子的,当链接到的组件是需要登录后才能查看,要能够跳转到登录页,然后登录成功后又跳回来之前想访问的页面。这里主要是用一个权限控制类...

总体概述

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

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