前置条件

  1. react,这里应用 umiJs脚手架
  2. 应用redux数据流,这里应用 dvaJS数据流
  3. 创立页面 「TestPage」,作为例子页面
  4. 创立按钮组件「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.jsconst 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' } 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    };}export default connect(mapStateToProps)(HOCAuth(Test))// 这是页面级的权限校验,应用 HOCAuth 包裹 Test// test/model.jsconst 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实现的权限校验零碎简略例子。欢送计划沟通、斧正

完结。