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

相关推荐
用户30587584891251 小时前
Connected-react-router核心思路实现
react.js
哑巴语天雨16 小时前
React+Vite项目框架
前端·react.js·前端框架
初遇你时动了情16 小时前
react 项目打包二级目 使用BrowserRouter 解决页面刷新404 找不到路由
前端·javascript·react.js
码农老起16 小时前
掌握 React:组件化开发与性能优化的实战指南
react.js·前端框架
前端没钱17 小时前
从 Vue 迈向 React:平滑过渡与关键注意点全解析
前端·vue.js·react.js
高山我梦口香糖20 小时前
[react] <NavLink>自带激活属性
前端·javascript·react.js
撸码到无法自拔20 小时前
React:组件、状态与事件处理的完整指南
前端·javascript·react.js·前端框架·ecmascript
高山我梦口香糖20 小时前
[react]不能将类型“string | undefined”分配给类型“To”。 不能将类型“undefined”分配给类型“To”
前端·javascript·react.js
乐闻x1 天前
VSCode 插件开发实战(四):使用 React 实现自定义页面
ide·vscode·react.js
irisMoon061 天前
react项目框架了解
前端·javascript·react.js