实现效果:
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; }