这几天从Vue转react,学习一下全家桶。
React-router很强大, 但是文档是纯英文而且不直接提供类似Vue的路由守卫,所以需要手写路由守卫,下面是一个写法,可参考,路由守卫的作用都知道,就不再赘述,最基础的功能就是对登录状态进行一个简单的验证。
首先创建几个页面:
-
Home:主页
-
Login:登录
-
Error:路由出错的展示页面(404)
然后创建router.js用来编写路由配置
步骤:
1.import必要的组件:
import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
BrowserRouter as Router ,
Switch ,
Route ,
useHistory ,
useLocation,
Redirect
} from 'react-router-dom';
2.配置路由数组:
const routerArr = [
{
path:"/login",
component:Login,
},
{
path:"/error",
component:ErrorPage
},
{
path:"/",
component:Home
}
]
3.编写路由守卫:
function RouterGuard(){
let history = useHistory();
let location = useLocation();
// 拿到路径
let { pathname } = location;
// 拿到当前路由
let thisRoute = routerArr.find((el)=>el['path'] == pathname);
let isLogin = sessionStorage.getItem('isLogin');
//如果没登录且页面为登录页的话渲染登录页
if(pathname == '/login' && !isLogin){
return <Route path={pathname} component={thisRoute['component']} exact/>
}
//如果已经登录渲染页面
if(isLogin){
//如果登陆了跳转login页,则重定向
if(pathname == '/login'){
return <Redirect to="/" />
}
// 判定路由是否存在,如果存在正常渲染
if(thisRoute){
return <Route path={pathname} component={thisRoute['component']} exact/>
}else{
//否则进入404页面
return <Redirect to="/error" />;
}
}else{
// 否则跳转到登录页
return <Redirect to="/login" />
}
}
可以做更多的拓展,比如通过在路由配置中添加字段实现传值/条件跳转等功能
4.渲染Router并抛出组件:
function Routes(){
return (
<Router>
<Switch>
<RouterGuard />
</Switch>
</Router>
)
}
export default Routes
然后渲染即可,子组件均可通过:
this.props.history
this.props.location
等方式的到父组件的方法,方便进行跳转等调用。
完整的Router.js:
import React from 'react';
import Login from './Login/index.js';
import Home from './Home/index.js';
import ErrorPage from './Error/index.js';
import {
BrowserRouter as Router ,
Switch ,
Route ,
useHistory ,
useLocation,
Redirect
} from 'react-router-dom';
const routerArr = [
{
path:"/login",
component:Login,
},
{
path:"/error",
component:ErrorPage
},
{
path:"/",
component:Home
}
]
function RouterGuard(){
let history = useHistory();
let location = useLocation();
let { pathname } = location;
// 拿到当前路由
let thisRoute = routerArr.find((el)=>el['path'] == pathname);
let isLogin = sessionStorage.getItem('isLogin');
//如果没登录且页面为登录页的话渲染登录页
if(pathname == '/login' && !isLogin){
return <Route path={pathname} component={thisRoute['component']} exact/>
}
//如果已经登录渲染页面
if(isLogin){
//如果登陆了跳转login页,则重定向
if(pathname == '/login'){
return <Redirect to="/" />
}
if(thisRoute){
return <Route path={pathname} component={thisRoute['component']} exact/>
}else{
return <Redirect to="/error" />;
}
}else{
// 否则跳转到登录页
return <Redirect to="/login" />
}
}
function Routes(){
return (
<Router>
<Switch>
<RouterGuard />
</Switch>
</Router>
)
}
export default Routes