官方提供了 react-transition-group 库来实现过渡动画,与vue官方提供的 transition 很类似,利用它实现过渡动画。
一、安装
npm : npm install react-transition-group --save
yarn : yarn add react-transition-group
二、使用
官网给出了4种API,分别是 Transition 、CssTransition 、SwitchTransition 、TransitionGroup,今天我们主要使用 CssTransition 与 TransitionGroup
CssTransition
被包裹dom在出现、进入、退出阶段利用 CssTransition 提供的 classNames 激活CSS动画
参数:in, timeout, unmountOnExit, classNames, onEntered,onExited,用法同Transition
案例:
import React, { Component } from 'react'
import '../../index.css'
import { CSSTransition } from 'react-transition-group'
export default class AnimationByCss extends Component {
constructor(props){
super(props)
this.state = {
show:false
}
}
hander = () => {
this.setState({
show:!this.state.show
})
}
render() {
let { show } = this.state
return (
<div>
<div className='shoppingCart_button' onClick={() => this.handler()}>{show ? '执行出场动画' : '执行入场动画'}</div>
<CSSTransition
in={this.state.show} // 如果this.state.show从false变为true,则动画入场,反之出场动画
timeout={1000} //动画执行1秒
classNames='fade' //自定义的class名
unmountOnExit // 当动画出场后在页面上移除包裹的dom节点
onEntered={(el) => { }} // 入场动画执行完毕的回调
onExited={(el) => { }} // 出场动画执行完毕的回调
>
<div className='main'></div>
</CSSTransition>
</div>
)
}
}
// index.css:
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.shoppingCart_button {
width: 100px;
padding: 10px 10px;
border: 1px #eee solid;
cursor: pointer;
user-select: none;
margin-bottom: 50px
}
/*被执行元素默认样式*/
.main {
opacity: 0;
transform: translateX(200px);
transition: all 0.5s linear;
width: 400px;
height: 400px;
background-color: #000;
border: 1px #eee solid;
border-radius: 10px
}
/*enter:入场前*/
.fade-enter {
opacity: 0;
}
/*enter-active:入场后到入场结束*/
.fade-enter-active {
transform: translateX(0px);
opacity: 1;
}
/*enter-done:入场动画执行完毕后,保持状态*/
.fade-enter-done {
transform: translateX(0px);
opacity: 1;
}
/*enter:出场前*/
.fade-exit {
opacity: 1;
}
/*enter-active:出场后到出场结束*/
.fade-exit-active {
transform: translateX(200px);
opacity: 0;
}
/*enter-done:出场动画执行完毕后,保持状态*/
.fade-exit-done {
opacity: 0;
}
TransitionGroup
列表形态的动画:如果页面上一组dom都需要添加动画效果,在最外面再加一个TransitionGroup即可
案例:
import React, {Component} from 'react'
import '../../index.css'
import { TransitionGroup, CSSTransition } from 'react-transition-group'
export default class ShoppingCart extends Component {
constructor(props) {
super(props)
this.state = {
list: [{text: 'Vue'}, {text: 'React'}, {text: 'Angular'}]
}
}
// ADD
add = () => {
let result = window.prompt('Add')
if (result){
this.setState({
list:[...this.state.list,{text:result}]
})
}
}
// delete
deleteItem = (index) => {
this.state.list.splice(index,1)
this.setState(['list'])
}
render() {
let { list } = this.state
return (
<div style={{paddingLeft: '100px'}}>
<div className='shoppingCart_button' onClick={() => this.add()}>Add item ...</div>
<TransitionGroup>
{list.map((item, index) => (
<CSSTransition
key={item.text}
timeout={500} //动画执行1秒
classNames='fade' //自定义的class名
>
<div className='todo_list' onClick={() => this.deleteItem(index)}>
<div className='todo_item'>
{item.text}
</div>
</div>
</CSSTransition>
))}
</TransitionGroup>
</div>
)
}
}
// index.css:
.todo_list {
transition: all 0.3s linear;
width: 400px;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px #999 solid;
border-radius: 10px;
margin-bottom: 10px;
background-color: #000000;
box-shadow: 1px 1px 5px 0 #000;
color: #fff;
}
/*enter:入场前*/
.fade-enter {
transform: translateX(300px);
opacity: 0;
}
/*enter-active:入场后到入场结束*/
.fade-enter-active {
transform: translateX(0px);
opacity: 1;
}
/*enter-done:入场动画执行完毕后,保持状态*/
.fade-enter-done {
transform: translateX(0px);
opacity: 1;
}
/*enter:出场前*/
.fade-exit {
opacity: 1;
}
/*enter-active:出场后到出场结束*/
.fade-exit-active {
transform: translateX(200px);
opacity: 0;
}
/*enter-done:出场动画执行完毕后,保持状态*/
.fade-exit-done {
opacity: 0;
}
根据上面的 CSS 过渡动画效果,下篇文章准备实现:利用 react-transition-group 实现APP路由切换翻页动画…