umi6.x + react + antd的项目增加403(无权限页面拦截),404,错误处理页面

  1. 首先在src/pages下创建403,404,ErrorBoundary

    403
    import { Button, Result } from 'antd';
    import { history } from '@umijs/max';

    const UnAccessible = () => (
    <Result
    status="403"
    title="403"
    subTitle="抱歉,您无权限访问当前页面"
    extra={<Button type="primary" onClick={()=>{
    history.push('/')
    }}>返回主页</Button>}
    />
    );
    export default UnAccessible;

    404
    import { Button, Result } from 'antd';
    import { history } from '@umijs/max';

    const NotFound = () => (
    <Result
    status="404"
    title="404"
    subTitle="抱歉,无法找到你需要的页面"
    extra={<Button type="primary" onClick={()=>{
    history.push('/')
    }}>返回主页</Button>}
    />
    );
    export default NotFound;

    ErrorBoundary(错误边界)
    import { Result, Button, Tooltip, Typography } from 'antd';
    import React from 'react';
    // eslint-disable-next-line @typescript-eslint/ban-types
    export default class ErrorBoundary extends React.Component {
    state = { hasError: false, errorInfo: '' };
    static getDerivedStateFromError(error) {
    return { hasError: true, errorInfo: error.message };
    }

    componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    // eslint-disable-next-line no-console
    console.log(error, errorInfo);
    }

    render() {
    if (this.state.hasError) {
    // You can render any custom fallback UI
    return (
    <Result
    status="500"
    title={抱歉,服务发生错误!请刷新页面}
    subTitle={<Tooltip title={this.state.errorInfo}>
    <Typography.Paragraph copyable={{
    text:this.state.errorInfo
    }}>错误信息</Typography.Paragraph>
    </Tooltip>}
    extra={
    <Button
    type="primary"
    onClick={() => {
    window.location.reload();
    }}
    >
    刷新页面
    </Button>
    }
    />
    );
    }
    return this.props.children;
    }
    }

  2. 在app.js配置

  3. 对于没有权限的页面,在浏览器输入地址,前端拦截,需要access.js方法拦截,src/access.js
    4中routes.js中配置的access就是作为key(accessObj获取的key要和routes.js中配置的access一致)

    /* eslint-disable array-callback-return */
    import allData from '../config/routes';

    //获取权限 key 根据 path 生成
    function convertToAccessArray(data) {
    let accessArray = [];
    data.map(obj => {
    if (obj.path && obj.path !== '/' && obj.path !== '/home') {
    // 去掉路径中的斜杠,并且将首字母大写
    const access = obj.path.replace(///g, '').charAt(0).toUpperCase() + obj.path.replace(///g, '').slice(1);
    accessArray.push(access);
    }
    if (obj.routes) {
    const childAccessArray = convertToAccessArray(obj.routes);
    accessArray = accessArray.concat(childAccessArray);
    }
    });

    return accessArray;
    }

    export default (initialState) => {

    const {menuData} = initialState;
    //后端返回的页面(路由)
    const AccessList = convertToAccessArray(menuData?.routes??[]);
    //全部页面
    const AllList = convertToAccessArray(allData?.routes);
    //结果对象 accessKey 对应配置的 routes 里面的 access
    // {
    // accessKey: true or false
    // }
    const accessObj = {};

    //添加权限
    AllList?.map(it=>{
    accessObj[it] = AccessList.includes(it);
    })

    return accessObj;
    };

//后端返回的页面(路由)格式类似:

[
    {
        "name": "首页",
        "key": "2024042410100000000",
        "path": "/home",
        "icon": null,
        "routes": []
    },
    {
        "name": "IoT管理",
        "key": "2024042410200000000",
        "path": "/iot",
        "icon": null,
        "routes": [
            {
                "name": "设备管理",
                "key": "2024042410200200000",
                "path": "/iot/device",
                "icon": "icon-shebeiguanli",
                "routes": [
                    {
                        "name": "设备台账",
                        "key": "2024042410200201000",
                        "path": "/iot/device/account",
                        "icon": null,
                        "routes": []
                    }
                ]
            }
        ]
    }
]
  1. 如果要对没有权限的页面进行拦截,还需要在routes.js配置access

    {
    path: '/',
    routes: [
    {
    path: '/',
    redirect: '/home',
    },
    {
    name: '首页',
    path: '/home',
    component: './Home',
    },
    {
    name: 'IoT管理',
    path: '/iot',
    access: 'Iot',
    routes: [
    {
    name: '设备清单',
    path: '/iot/devicelist',
    icon: 'icon-zhiduguifan',
    component: './Iot/DeviceList',
    access: 'Iotdevicelist',
    }
    ],
    },
    {
    path:'/*',
    name: '404',
    component: './404',
    hideInMenu: true,
    },
    ],
    }

相关推荐
screct_demo7 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
光头程序员16 小时前
grid 布局react组件可以循数据自定义渲染某个数据 ,或插入某些数据在某个索引下
javascript·react.js·ecmascript
limit for me16 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者16 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
VillanelleS19 小时前
React进阶之高阶组件HOC、react hooks、自定义hooks
前端·react.js·前端框架
傻小胖20 小时前
React 中hooks之useInsertionEffect用法总结
前端·javascript·react.js
flying robot1 天前
React的响应式
前端·javascript·react.js
GISer_Jing2 天前
React+AntDesign实现类似Chatgpt交互界面
前端·javascript·react.js·前端框架
智界工具库2 天前
【探索前端技术之 React Three.js—— 简单的人脸动捕与 3D 模型表情同步应用】
前端·javascript·react.js
我是前端小学生2 天前
我们应该在什么场景下使用 useMemo 和 useCallback ?
react.js