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,
    },
    ],
    }

相关推荐
Jacky-0087 小时前
Node + vite + React 创建项目
前端·react.js·前端框架
用户47949283569159 小时前
为什么我的react项目启动后,dom上的类名里没有代码位置信息
前端·react.js
Jonathan Star14 小时前
在 React 生态中,有多个成熟的 虚拟列表 npm 库
react.js·arcgis·npm
Dontla14 小时前
前端状态管理,为什么要状态管理?(React状态管理、zustand)
前端·react.js·前端框架
宋辰月14 小时前
学习react第一天
javascript·学习·react.js
骑自行车的码农2 天前
React SSR 技术实现原理
算法·react.js
Cxiaomu2 天前
React Native App 自动检测版本更新完整实现指南
javascript·react native·react.js
小p2 天前
react学习6:受控组件
前端·react.js
sophie旭2 天前
一个偶现bug引发的onKeyDown 和 onChange之战
前端·javascript·react.js
光影少年2 天前
React Native第六章
javascript·react native·react.js