React - hooks + hoc 实现权限校验系统(按钮页面等权限)
Posted liaoxinyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React - hooks + hoc 实现权限校验系统(按钮页面等权限)相关的知识,希望对你有一定的参考价值。
前置条件
- react,这里使用 umiJs脚手架
- 使用redux数据流,这里使用 dvaJS数据流
- 创建页面 「TestPage」,作为例子页面
- 创建按钮组件「MyInput」,作为例子按钮
部分代码目录
Demo/
node_modules/
dist/
src/
components/
MyInput/
index.js // 公共组件,input
HOCAuth/
index.js // 核心权限校验组件
pages/
test/
index.js // 我们的测试页面
model.js // test页面的状态
home/
index.js // home 页面
model.js // home 页面的状态
models/
global.js // 最顶层的全局公共状态
services/ // api等等
utils/
app.js // 入口函数
router.js // 路由配置
package.json
...等等
思路
如何校验权限?
我们将需要校验的(按钮或页面等)目标组件,通过一个公共组件包裹(即hoc组件),在这个hoc组件中判断目标组件的权限编码是否存在于权限表里,「若存在」则当前有权限访问,渲染。「不存在」则返回 null
。
那么,我们首先要储存一份权限表,供所有组件使用。再为每个组件设置对于的权限编码。
这里我们对页面的权限编码配置规则为 \'数字-数字\',如:\'1-2\'、\'1-3\'等等。页面级组件使用\'-\'连接。
按钮级的权限编码为:\'1-1_1\'、\'1-1_2\'等等。 按钮级组件使用\'_\'连接。
如我们当前 test
页面编码为 \'1-1\',且该下面也有两个按钮级组件,那么该组件编码分别为 \'1-1_1\'、\'1-1_2\'。
例子:
const auth = {
\'1-1\': true,
\'1-1_1\': true
} // 权限表
const testPageAuthKey = \'1-1\' // test页面的权限编码
const inputAuthKey = \'1-1_1\' // test页面下的input组件权限编码
若 auth[authKey] === true 即有权限,渲染对应组件
接下来定义状态:
每个页面有单独的 model.js
(即redux中的store),用于存放该页面的状态。global.js
存放项目最顶层的状态,为公共状态。
global
中储存一份权限表 auth
,为所有按钮或页面的权限。渲染按钮或页面前,校验当前是否有权限,无权限则返回 null
。
例子
// global.js
const Model = {
namespace: \'Global\',
state: {
auth: {
\'1-1\': true, // 表示拥有test页面权限
\'1-1_1\': true, // 表示拥有test页面下的input组件权限
} // 当前所有的权限
},
effects: {
* fetchAuth({ payload, callback }, { call, put }) {
// 登录后调用api获取当前用户所拥有的权限配置,更新掉auth
const { auth } = yield call(apiFetchAuthFromServe, payload)
yield put({
type: \'save\',
payload: {
auth
},
});
if (callback) callback();
}
},
reducers: {
save (state, { payload }) {
return {
...state,
...payload,
}
};
},
}
components/MyInput/index.js,input组件
import React, { useRef, useMemo, memo } from \'react\';
import HOCAuth from \'../HOCAuth\';
const Input = props => {
const {
onChange,
value,
defaultValue,
} = props;
const input = useRef(null);
const cur = useMemo(() => {
if (value) return value;
if (defaultValue) return defaultValue;
}, [defaultValue, value]);
function onInputChange (e) {
if (onChange) onChange(e.target.value);
}
return (
<input type="text" ref={ input } defaultValue={ cur } onChange={ onInputChange }/>
);
};
export default memo(HOCAuth(Input)); // 这里使用HOCAUth包裹 Input
再看看使用:
// test/index.js test页面
import React from \'react\';
import { connect } from \'dva\';
import HOCAuth from \'@/components/HOCAuth\'
import MyInput from \'@/components/MyInput\'
const Test = props => {
console.log(props)
return (
<div>
<MyInput defaultValue={ \'default\' } auth={ props.Global.auth } authKey={ \'1-1_1\' } /> // 传递authKey,表示该组件对应的权限编码
</div>
);
};
function mapStateToProps ({ Global, Test }) {
return {
auth: Global.auth, // 订阅global.js中的auth
authKey: Test.authKey, // 当前test页面的权限编码,从model中获取
Test, // test/model.js
Global
};
}
export default connect(mapStateToProps)(HOCAuth(Test))
// 这是页面级的权限校验,使用 HOCAuth 包裹 Test
// test/model.js
const Model = {
namespace: \'Test\',
state: {
authKey: \'1-1\', // 当前test页面的权限编码
},
...略
}
接下来是我们的核心组件HOCAuth,components/HOCAuth/index.js
import React from \'react\';
const HOCAuth = BaseComponent => (props) => {
const { auth, authKey, ...others } = props;
if (!auth || !authKey) return null;
return (
auth[authKey] ?
<BaseComponent { ...others }/> : null // 过滤掉 auth与authKey
);
};
export default HOCAuth;
// 简单不?
以上为react hooks + hoc实现的权限校验系统简单例子。欢迎方案沟通、指正
结束。
以上是关于React - hooks + hoc 实现权限校验系统(按钮页面等权限)的主要内容,如果未能解决你的问题,请参考以下文章
是否可以通过使用 HOC(高阶组件)在类组件中使用 React Hooks?