這幾天從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