实现效果:
umi实现路由动画
文件目录结构:
.umirc.ts文件配置:
routes: [
{
path: '/login',
component: '@/pages/login/login.tsx',
},
{
path: '/',
component: '@/pages/home/home.tsx',
exact: false,
wrappers: ['@/wrappers/auth'],
routes: [
{
path: '/',
component: '@/pages/home/home/home',
wrappers: ['@/wrappers/auth'],
},
{
path: '/type',
component: '@/pages/home/type/type',
wrappers: ['@/wrappers/auth'],
},
{
path: '/shopping',
component: '@/pages/home/shop/shop',
wrappers: ['@/wrappers/auth'],
},
],
},
],
home.tsx文件配置:
import React from 'react';
import { NavBar, TabBar } from 'antd-mobile';
import './home.less';
import {
useHistory,
useLocation,
MemoryRouter as Router,
Switch
} from 'react-router-dom';
import {
AppOutline,
UnorderedListOutline,
UserOutline,
FileOutline,
} from 'antd-mobile-icons';
import { TransitionGroup, CSSTransition } from 'react-transition-group'
export default (props: any) => {
const tabs = [
{
key: '/',
title: '首页',
icon: <AppOutline />,
},
{
key: '/type',
title: '分类',
icon: <UnorderedListOutline />,
},
{
key: '/shopping',
title: '购物车',
icon: <FileOutline />,
},
{
key: '/person',
title: '个人',
icon: <UserOutline />,
},
];
const history = useHistory();
const location = useLocation();
const { pathname } = location;
const setRouteActive = (value: string) => {
history.push(value);
};
const routerType = {
'POP': 'back',
'PUSH': 'dg',
'REPLACE': 'dg'
}
return (
<div className="app">
<div className="body">
<TransitionGroup className='transition_wrapper' style={{ width: '100%', height: '100%' }} childFactory={(child) => (
React.cloneElement(child, { classNames: routerType[history.action] })
)}>
<CSSTransition key={props.location.pathname} appear timeout={1000}>
{props.children}
</CSSTransition>
</TransitionGroup>
</div>
<div className="bottom">
<TabBar activeKey={pathname} onChange={(value: any) => setRouteActive(value)}>
{tabs.map((item) => (
<TabBar.Item key={item.key} icon={item.icon} title={item.title} />
))}
</TabBar>
</div>
</div>
);
};
home.less文件配置:
.app {
height: 100vh;
display: flex;
flex-direction: column;
}
.top {
flex: 0;
border-bottom: solid 1px var(--adm-color-border);
}
body{
margin: 0;
}
.body {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
.bottom {
flex: 0;
border-top: solid 1px var(--adm-color-border);
background-color: #fff !important;
z-index: 200;
position: fixed;
width: 100vw;
bottom: 0;
}
.dg-enter {
transform: translate(100%, 0);
}
.dg-enter-active {
transition: 3s;
transform: translate(0);
}
.dg-enter-done {
transform: translate(0);
}
.dg-exit-active {
transition: 1s;
transform: translate(-100%, 0);
}
.back-enter-active {
transition: all 3s;
transform: translate(0, 0) !important;
}
.back-enter-done {
transform: translate(0, 0) !important;
}
.back-enter {
z-index: 5 !important;
transform: translate(-100%, 0);
}
.back-exit-active {
opacity: 0;
transition: all 3s;
transform: translate(100%, 0) !important;
}