过渡动画
React社区提供了react-transition-group用来完成过渡动画,该库可以实现组件的入场和离场- 官网: reactcommunity.org/react-trans…
- 安装
react-transition-group第三方库
npm i react-transition-group --save
react-transition-group主要包含四个组件:
- Transition: 该组件是和平台无关的组件
- CSSTransition: 通常使用该组件来完成过渡动画效果
- SwitchTransition: 可控制两个组件显示和隐藏的切换
- TransitionGroup: 将多个动画组件包裹在其中,一般用于列表中元素的动画
CSSTransition
CSSTransition是基于Transition组件构建的CSSTransition执行过程中有三个状态:appear、enter、exit
对应的三种状态都需要定义对应的
CSS样式
- 开始状态: 对于的类是
-appear、-enter(进入)、exit(离开) - 执行动画: 对应的类是
-appear-active、-enter-active、-exit-active - 执行结束: 对应的类是
-appear-done、-enter-done、-exit-done
import { CSSTransition } from 'react-transition-group';
import './style.css';
<div>
<button onClick={e => this.setState({ isShowTitle: !isShowTitle })}>显示/隐藏</button>
<CSSTransition
in={isShowTitle} // 判断显示的条件
classNames='title' // 过渡类名
timeout={2000} // 过渡时间(必须)
unmountOnExit // 退出时销毁
>
<h2>App</h2>
</CSSTransition>
</div>
/* 定义进入时的过渡动画 */
.title-enter {
opacity: 0;
}
.title-enter-active {
opacity: 1;
transition: opacity 2s ease;
}
常见属性
-
in: 触发进入或者退出状态
- 为
true时触发进入状态,会添加-enter,-enter-acitve的class开始执行动画,结束后将其移除,并添加-enter-done的class - 为
false时触发退出状态,会添加-exit、-exit-active的class开始执行动画,结束后会移出 并添加-enter-done的class
- 为
-
unmountOnExit:组件会在执行退出动画结束后被销毁掉
-
classNames: 对应的
class名称 -
timeout: 过渡动画的时间
-
appear: 是否在初次进入添加动画(需要和
in同时为true)
<CSSTransition
in={isShowTitle}
classNames='title'
timeout={2000}
unmountOnExit
appear
>
.title-enter, .title-appear {
opacity: 0;
}
.title-enter-active, .title-appear-active {
opacity: 1;
transition: opacity 2s ease;
}
钩子函数
CSSTransition对应的钩子函数,主要为了检测动画的执行过程,来完成一些JavaScript的操作
主要的钩子函数如下:
onEnter: 在进入动画之前被触发onEntering: 在应用进入动画时被触发onEntered: 在应用进入动画结束后被触发onExit: 在进入动画之前被触发onExiting: 在应用进入动画时被触发onExited: 在应用进入动画结束后被触发
<CSSTransition
in={isShowTitle}
classNames='title'
timeout={2000}
unmountOnExit
onEnter={e => console.log('开始执行动画')}
onEntering={e => console.log('执行进入动画')}
onEntered={e => console.log('进入动画结束')}
onExit={e => console.log('开始离开动画')}
onExiting={e => console.log('执行离开动画')}
onExited={e => console.log('离开动画结束')}
>
SwitchTransition
SwitchTransition可以完成两个组件之间切换的动画- 使用
react-transition-group中提供的SwitchTransition来实现该类型的动画
import { SwitchTransition, CSSTransition } from 'react-transition-group';
<div>
<SwitchTransition mode='out-in'> {/* mode为切换的模式 */}
<CSSTransition
key={isLogin ? 'exit' : 'login'} {/* 用于执行切换动画 */}
classNames="login"
timeout={1000}
>
<button onClick={e => this.setState({ isLogin: !isLogin })}>{isLogin?'退出':'登录'}</button>
</CSSTransition>
</SwitchTransition>
</div>
.login-enter {
transform: translateX(100px);
opacity: 0;
}
.login-enter-active {
transform: translateX(0);
opacity: 1;
transition: all 1s ease;
}
.login-exit {
transform: translateX(0);
opacity: 1;
}
.login-exit-active {
transform: translate(-100px);
opacity: 0;
transition: all 1s ease;
}
- 通过
CSSTransition不同的key属性切换,让切换动画执行
mode属性有两个值
- in-out: 表示新组件先进入,旧组件再移除
- out-in: 表示就组件先移除,新组件再进入
TransitionGroup
- 当有一组动画时,需要将这些
CSSTransition放入到一个TransitionGroup中来完成动画
const books = [
{ name: '你不知道的JS', price: 99, id: 1},
{ name: 'JS高级程序设计', price: 88, id: 2},
{ name: 'VueJS高级设计', price: 77, id: 3}
];
<div>
<h2>书籍列表</h2>
<TransitionGroup component='ul'> {/* component: 指定需要渲染的标签 */}
{
books.map((item) => (
<CSSTransition key={item.id} classNames='book' timeout={1000}>
<li key={item.id}>{item.name}-{item.price}</li>
</CSSTransition>
))
}
</TransitionGroup>
<button onClick={e => this.addNewBook()}>添加新书籍</button>
</div>
- 此处的
key最好保证是唯一的,否则动画可能出现差错
.book-enter {
transform: translateX(100px);
opacity: 0;
}
.book-enter-active {
transform: translateX(0);
opacity: 1;
transition: all 1s ease;
}