一、效果演示
react-transition-group转场动画: (如果无法播放可点击下载查看)
二、安装
这个演示界面是通过路由实现的,谈到这个我们就不得不提到成熟的react动画库:react-transition-group 首先我们通过npm进行安装(这里假定你已经学会了使用react-router-dom,react-router,react-router-config)如果你还没有学习,那我建议你稍微进行学习后再来了解路由动画。 安装命令:
1
| npm install react-transition-group --save
|
三、完整源码
不想看实现过程的请直接看源码实现并进行copy: index.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import React from "react"; import { CSSTransition, TransitionGroup } from "react-transition-group"; import { Switch, Route, withRouter } from "react-router-dom"; import "./index.css";
/** * * @param {way} props * @description 用于页面路由跳转 通过way指定跳转方式,指定way=refade * 则反向 * */ const ANIMATION_MAP = { PUSH: "fade", POP: "refade", }; function AnimationGo(props) { const { children } = props; // console.log(props.history.action); // 根据动作自行判断前进和后退 /*使用React.cloneElement API对props中的classNames这一props进行修改 */ return ( <Route render={({ location }) => ( <TransitionGroup
childFactory={(child) => React.cloneElement(child, { classNames: ANIMATION_MAP[props.history.action], }) } > <CSSTransition timeout={500} key={location.pathname}> <Switch location={location}>{children}</Switch> </CSSTransition> </TransitionGroup> )} ></Route> ); }
export default withRouter(AnimationGo);
|
index.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| .fade-enter,.fade-appear { transform: translateX(100%); }
.fade-enter-active,.fade-appear { transform: translateX(0); transition: transform 0.5s ease; }
.fade-exit { transform: translateX(0); }
.fade-exit-active { transform: translateX(-100%); transition: transform 0.5s ease; }
.fade-exit-done { transform: translateX(-100%); }
.refade-enter,.refade-appear { transform: translateX(-100%); }
.refade-enter-active,.refade-appear-active { transform: translateX(0%); transition: transform 0.5s ease; }
.refade-enter-done { transform: translateX(0%); }
.refade-exit { transform: translateX(0%); }
.refade-exit-active { transform: translateX(100%); transition: transform 0.5s ease; }
.refade-exit-done { transform: translateX(100%); }
|
挂载组件:
1 2 3 4 5 6 7 8 9
| function App() { return ( <div className="App"> <Router> <AnimationGo>{renderRoutes(routes)}</AnimationGo> </Router> </div> ); }
|
四、组件编写分析
创建组件编写文件夹,在这里同样不加赘述 首先导入我们所需要的一切控件,在这里,我们将通过函数式组件来构建封装这个组件
1 2 3 4
| import React from "react"; import { CSSTransition, TransitionGroup } from "react-transition-group"; import { Switch, Route, withRouter } from "react-router-dom"; import "./index.css";
|
导入的React不必多说,这是编写JSX必须的操作。 关于react-transition-group,它的用法看上去很类似Vue内置的Transition组件,实际上它就是以vue的transition组件为灵感进行编写的。
A transition component inspired by the vue transition modes.
在react-transition-group中,其提供了如下四个组件和一个config对象: 由于本文重点在于路由跳转动画的实现,所以它的各个详细作用,请自行查看官网文档: 我们在这里需要用到的是CSSTransiton以及TransitionGroup这两个组件,我们先来了解一下这两个组件:
- CSSTransition用于通过不同CSS的指定形式来展现动画,它有-enter(入场动画初始状态,第一帧),-enter-active(入场动画进行时),-enter-done(入场完成后的样式,一般就是-enter-active所指定的末状态,可以不指定),-exit(离场动画初始状态,第一帧),-exit-active(离场状态进行时),-exit-done(与enter-done类似,同样也几乎没有太大意义)这几个关键的CSS类别。 而CSSTransion有以下几个关键的属性:in,timeout,classNames(注意是classNames,不是className),in属性就是动画开关,classNames即为前文所提到CSS属性名称的前缀部分,timeout即为动画维持时间。
- TransitionGroup组件,如同它的字面意义,它用于管理一组的过渡组件(比如上文的CSSTransion组件,以及用于其他平台的Transition组件),也就是说,它的子组件,一般是包裹着CSSTransion/Transion组件的组件,它的子组件CSSTransion/Transion上必须指定key属性,利用React根据key值进行diff算法的特性,当发生状态改变的时候,它会暂时保留原本需要移除或变化的子组件,并执行CSSTransion/Transion指定的动画。
简单来说,CSSTransion组件用于进行单个组件的动画过程,而通过TransitionGroup可以对多个由 CSSTransion构成的组件进行管理,而在路由切换这一过程中,本质上就是两个view级别(视图级别)组件的切换过程,这一过程中,在必定存在一个如下图所示的过程: 也就是说,A与B在进行动画切换的时候必定同时存在,这时候就需要使用到TransitionGroup了。