封装loading组件src\components\Loading\index.jsx
需安装classnames组件
loading层需要支持全屏或者部分屏定位
import React from 'react';
import './index.less';
import classnames from 'classnames';
const Loading = ({isLoading, part=false}) => {
const loadingStyle = part ? {
position: 'absolute',
top: '50%',
left: '50%',
height: '100px',
width: '100px',
transform: 'translate(-50%, -50%)',
} : {};
return (
<div style={loadingStyle} className={classnames('loader', 'fullScreen', {hidden: !isLoading})}>
<div className='wrapper'>
<div className='inner'></div>
<div className='text'>LOADING</div>
</div>
</div>
);
};
export default Loading;
src\components\Loading\index.less
基本样式
.loader {
background-color: #fff;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
z-index: 100000;
display: flex;
justify-content: center;
align-items: center;
opacity: 1;
text-align: center;
&.fullScreen {
position: fixed;
}
.wrapper {
width: 100px;
height: 100px;
display: inline-flex;
flex-direction: column;
justify-content: space-around;
}
.inner {
width: 40px;
height: 40px;
margin: 0 auto;
text-indent: -12345px;
border-top: 1px solid rgba(0, 0, 0, 0.08);
border-right: 1px solid rgba(0, 0, 0, 0.08);
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
border-left: 1px solid rgba(0, 0, 0, 0.7);
border-radius: 50%;
z-index: 100001;
animation: spinner 600ms infinite linear;
}
.text {
width: 100px;
height: 20px;
text-align: center;
font-size: 12px;
letter-spacing: 4px;
color: #000;
}
&.hidden {
z-index: -1;
opacity: 0;
transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s;
}
}
@keyframes spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
主要通过useSelector实现,dva里effects定义的都会产生loading状态
const loading = useSelector(state => state.loading);
//console.log(loading,'loading');

src\layouts\BaseLayout.jsx
import { Outlet, history, useNavigate, useLocation, useSelector } from 'umi';
import { Layout, Menu } from 'antd';
const { Header, Footer, Sider, Content } = Layout;
import SildeBar from 'components/SildeBar';
import { useState, useEffect } from 'react';
import './BaseLayout.less';
import CommonHeader from 'components/CommonHeader';
import NotFoundPage from '../pages/404Page';
import Loading from 'components/Loading';
export default function BackLayout({children}) {
const [collapse, setCollapse] = useState(false);
const changeCollapse = () => {setCollapse(!collapse);}
const navigate = useNavigate();
const location = useLocation();
const pathname = location.pathname;
const routeList = sessionStorage.getItem('routeList') ? JSON.parse(sessionStorage.getItem('routeList')) : [];
const loading = useSelector(state => state.loading);
//console.log(loading,'loading');
// useEffect(() => {
// console.log(pathname,'pathname');
// if (pathname === '/') {
// navigate(routeList[0].route, { replace: true });
// }
// }, [pathname, routeList, navigate]);
//特殊处理,跳首页及没有跳404
const pageJudge = () => {
if (location.pathname === '/') {
//history.replace(routeList[0]?.route || '/');
navigate(routeList[0]?.route || '/', { replace: true });
return true;
}
return routeList.some(item => item.route === location.pathname);
}
return (
<Layout className="container">
<SildeBar Sider={Sider} Menu={Menu} collapse={collapse} />
<Layout>
<CommonHeader
Header={Header}
collapse={collapse}
changeCollapse={changeCollapse}
/>
<Content className="main-content">{pageJudge() ? (
<>
<Loading part={true} isLoading={loading?.effects['dashboard/initDashboardList']} />
<Outlet />
</>): (<NotFoundPage />)}</Content>
</Layout>
</Layout>
);
}




