作用
- 阻止页面越权
- 不用调用接口即可阻止页面越权
例如:某普通管理员登录,即使知道超管的页面路由地址,也看不到越权的页面。
实现
参考reactrouter官方教程,结合路由嵌套配置,和路由鉴权示例。
https://reactrouter.com/web/example/auth-workflow
https://reactrouter.com/web/example/route-config
代码
-
router.js
路由配置(增加权限字段)
import MainPart from '../pages/Layout/MainPart';
import Login from '../pages/login/Index.jsx';
import LiveList from '../pages/LiveList/Index.jsx';
import Authority from '../pages/Authority/Index.jsx';
import LiveDetail from '../pages/LiveDetail/Index.jsx';
export default [
{
path: '/',
component: Login,
exact: true
},
{
path: '/login',
component: Login
},
{
component: MainPart,
routes: [
{
path: '/authority',
component: Authority,
auth:[99,98]
},
{
path: '/liveList',
component: LiveList,
auth:[97,98,99]
},
{
path: '/liveDetail',
component: LiveDetail,
},
]
},
];
-
index.js
引入
组件
import React, {useReducer,Fragment } from 'react';
import {HashRouter as Router, Route, Switch,Redirect, } from 'react-router-dom';
import ReactDom from 'react-dom';
import routers from './router';
import {defaultState, reducer, COMMON_CONTEXT} from './COMMON/store';
import RouterGuard from './RouterGuard.js';
function Index() {
const [state, dispatch] = useReducer(reducer, defaultState);
return (
{routers.map((route, i) => (
))}
);
}
document.title = '和家亲直播能力平台';
ReactDom.render( , document.querySelector('#app'));
-
RouterGuard.js
增加拦截逻辑
function RouterGuard(route) {
const {state} = useContext(COMMON_CONTEXT);
console.log(state);
return (
(
route.auth?.indexOf(Number(state.authCode))==-1?
:
)}
/>
);
}
export default RouterGuard;
- 嵌套路由处理
{routes.map((route, i) => (
))}
- 登录后,保存权限配置
const {dispatch} = useContext(COMMON_CONTEXT);
const function loginApi=()=>{
//省略登录逻辑代码
dispatch({
authToken,
authUserCode: userCode,
authCode,
authRole,
authPhone
});
}
HOOKS 相关知识点
useContext与useReducer 代替 redux
useContext
const value = useContext(MyContext);
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的的 value prop 决定。
当组件上层最近的更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
);
}
function Toolbar(props) {
return (
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
);
}
useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
useState
的替代方案。它接收一个形如 (state, action) => newState
的 reducer,并返回当前的 state 以及与其配套的 dispatch
方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)
在某些场景下,useReducer
会比 useState
更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer
还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch
而不是回调函数 。
以下是用 reducer 重写 useState
一节的计数器示例:
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
>
);
}