Open xianzou opened 3 years ago
移动端底部有菜单强烈建议采用flex竖向布局,不要使用position: fixed去定位菜单到底部 原React路由切换效果
移动端底部有菜单强烈建议采用flex竖向布局,不要使用position: fixed去定位菜单到底部
position: fixed
yarn add react-transition-group
import {CSSTransition, TransitionGroup} from 'react-transition-group'; const ANIMATION_MAP = { PUSH: 'forward', POP: 'back', REPLACE: 'replace'// 底部菜单的页面不需要使用动态路由,底部菜单使用replace替换路径,防止菜单也会跟着转场动画 } <TransitionGroup className={'router-wrapper'} childFactory={child => React.cloneElement( child, {classNames: ANIMATION_MAP[history.action]} )} > <CSSTransition timeout={500} key={location.pathname} > <Suspense fallback={<div>加载中...</div>}> <Switch> <Route exact path={'/'} component={HomePage} /> <Route exact path={'/about'} component={AboutPage} /> <Route exact path={'/list'} component={ListPage} /> <Route exact path={'/detail'} component={DetailPage} /> </Switch> </Suspense> </CSSTransition> </TransitionGroup>
import { HomePage, AboutPage, ListPage, DetailPage } from '@/components/component/index'; const HomePage = lazy(() => import('@/components/component/HomePage')); const AboutPage = lazy(() => import('@/components/component/AboutPage')); const ListPage = lazy(() => import('@/components/component/ListPage')); const DetailPage = lazy(() => import('@/components/component/DetailPage')); network 页面会闪
:global{ .router-wrapper { height: 100%; } .forward-enter { opacity: 0; transform: translateX(100%); box-shadow: 0 4px 7px rgba(0,0,0,.4); transition-timing-function:linear; } .forward-enter-active { opacity: 1; transform: translateX(0); transition: all 120ms; transition-timing-function:linear; } .forward-exit { opacity: 1; transform: translateX(0); transition-timing-function:linear; } .forward-exit-active { opacity: 0; transform: translateX(-100%); transition: all 120ms; transition-timing-function:linear; } .back-enter { opacity: 0; transform: translateX(-100%); box-shadow: 0 4px 7px rgba(0,0,0,.4); transition-timing-function:linear; } .back-enter-active { opacity: 1; transform: translateX(0); transition: all 120ms; transition-timing-function:linear; } .back-exit { opacity: 1; transform: translateX(0); transition-timing-function:linear; } .back-exit-active { opacity: 0; transform: translate(100%); transition: all 120ms; transition-timing-function:linear; } .replace-enter >div:first-child{ opacity: 0.01; } .replace-enter-active >div:first-child{ opacity: 1; transition: opacity 250ms ease-in; } .replace-exit >div:first-child{ opacity: 1; } .replace-exit-active >div:first-child{ opacity: 0.01; transition: opacity 250ms ease-in; } }
import { Switch, Route, withRouter, HashRouter } from 'react-router-dom'; const Routes = withRouter(({ history, location }) => ( <TransitionGroup className={'router-wrapper'} childFactory={child => React.cloneElement( child, { classNames: ANIMATION_MAP[history.action] } )} > <CSSTransition timeout={500} key={location.pathname} > <Suspense fallback={<div>加载中...</div>}> <Switch> <Route exact path={'/'} component={HomePage} /> <Route exact path={'/about'} component={AboutPage} /> <Route exact path={'/list'} component={ListPage} /> <Route exact path={'/detail'} component={DetailPage} /> </Switch> </Suspense> </CSSTransition> </TransitionGroup> )); export default () => { return ( <HashRouter> <Routes /> </HashRouter> ); };
<div className="mobile-main"> <Suspense fallback={<Loading />} maxDuration={500}> <Switch location={location}> ... </Switch> </Suspense> </div>
.mobile-main{ position: relative; top: 0; bottom: 0; left: 0; right: 0; height: 100%; }
https://cli.im/ 二维码生成
其他问题
## router.js import './index.scss'; import React, { lazy, Suspense } from 'react'; import { Route, Switch, HashRouter, withRouter } from 'react-router-dom'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; const HomePage = lazy(() => import('@/components/component/HomePage')); //路由组件 const AboutPage = lazy(() => import('@/components/component/AboutPage')); //路由组件 const ListPage = lazy(() => import('@/components/component/ListPage')); //路由组件 const DetailPage = lazy(() => import('@/components/component/DetailPage')); //路由组件 // import { HomePage, AboutPage, ListPage, DetailPage } from '@/components/component/index'; const ANIMATION_MAP = { PUSH: 'forward', POP: 'back', REPLACE: 'replace' }; const Router = withRouter(({ history, location }) => ( <TransitionGroup className={'router-wrapper'} fade childFactory={child => React.cloneElement( child, { classNames: ANIMATION_MAP[history.action] } )} > <CSSTransition timeout={500} key={location.pathname} > <div className="mobile-main"> <Suspense fallback={<div>加载中...</div>}> <Switch> <Route exact path={'/'} component={HomePage} /> <Route exact path={'/about'} component={AboutPage} /> <Route exact path={'/list'} component={ListPage} /> <Route exact path={'/detail'} component={DetailPage} /> </Switch> </Suspense> </div> </CSSTransition> </TransitionGroup> )); export default () => (<HashRouter><Router /></HashRouter>);
:global{ .router-wrapper { height: 100%; } .mobile-main{ position: relative; top: 0; bottom: 0; left: 0; right: 0; height: 100%; } .forward-enter { opacity: 0; transform: translateX(100%); } .forward-enter-active { opacity: 1; transform: translateX(0); transition: all 500ms; } .forward-exit { opacity: 1; transform: translateX(0); } .forward-exit-active { opacity: 0; transform: translateX(-100%); transition: all 500ms; } .back-enter { opacity: 0; transform: translateX(-100%); } .back-enter-active { opacity: 1; transform: translateX(0); transition: all 500ms; } .back-exit { opacity: 1; transform: translateX(0); } .back-exit-active { opacity: 0; transform: translate(100%); transition: all 500ms; } .replace-enter >div:first-child{ opacity: 0.01; } .replace-enter-active >div:first-child{ opacity: 1; transition: opacity 250ms ease-in; } .replace-exit >div:first-child{ opacity: 1; } .replace-exit-active >div:first-child{ opacity: 0.01; transition: opacity 250ms ease-in; } }
import 'bootstrap/dist/css/bootstrap.min.css'; import 'font-awesome/css/font-awesome.min.css';// shareui-font版本迁移完成之后删除该依赖 import '@share/shareui-html'; import '@share/shareui-font'; import '@/components/form'; import dva from 'dva'; import router from './router'; // 1. Initialize const app = dva(); // 2. Plugins // app.use({}); // 3. Model // app.model(); // 4. Router app.router(router); // 5. Start app.start('#root');
底部菜单路由,不用懒加载,不然会闪一下,其他非菜单页可以使用
移动端添加转场动画
实现的效果
实现
安装官方推荐动画库依赖
使用
懒加载和非懒加载的区别
引入样式
改造dva路由
懒加载没有效果?
试下不使用懒加载,不使用懒加载有效果
改造适合懒加载
修改index.scss,添加样式
大功告成
其他效果
项目运用
https://cli.im/ 二维码生成
其他问题
完整代码
样式
入口JS