1.使用CSS实现动画
本例中,只保留了App
这一个组件,代码如下:
import React, {Component, Fragment} from 'react';
import './style.css' //引入的CSS文件
class App extends Component {
constructor(props) {
super(props);
this.state = {
show: true // 控制hello是否显示
};
this.handleToggle = this.handleToggle.bind(this);
}
render() {
return (
<Fragment>
{/*根据show的真值修改类名*/}
<div className={this.state.show ? 'show' : 'hide'}>hello</div>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
// 让show不断变换真值
handleToggle() {
this.setState({
show: this.state.show ? false : true
})
}
}
export default App;
style.css文件:
.show{
opacity: 1;
transition: all 1s ease-in;
}
.hide{
opacity: 0;
transition: all 1s ease-in;
}
如果实现动画,也可以使用keyframe
.show{
animation: show-item 2s ease-in forwards;
}
.hide{
/*forwards 使得动画效果保留最后一帧,即hide-item进行到100%的样式*/
animation: hide-item 2s ease-in forwards;
}
@keyframes show-item {
0%{
opacity: 0;
color: red;
}
50%{
opacity: 0.5;
color: green;
}
100%{
opacity: 1;
color: blue;
}
}
@keyframes hide-item {
0%{
opacity: 1;
color: red;
}
50%{
opacity: 0.5;
color: green;
}
100%{
opacity: 0;
color: blue;
}
}
demo地址: React-TodoList示例——CSS的使用
2.使用react-transition-group实现动画
这是一个js框架,源码地址:react-transition-group
-
使用命令
npm install react-transition-group --save
进行安装。
该框架包含Transition
,CSSTransition
,SwitchTransition
,TransitionGroup
,我们主要使用CSSTransition,官方文档地址:CSSTransition -
组件中引入CSSTransition模块:
import { CSSTransition } from 'react-transition-group'
-
插件属性配置、 设置样式(.js文件、.css文件)
import React, {Component, Fragment} from 'react';
import { CSSTransition } from 'react-transition-group';
import './style.css'
class App extends Component {
constructor(props) {
super(props);
this.state = {
show: true
};
this.handleToggle = this.handleToggle.bind(this);
}
render() {
return (
<Fragment>
{/*要使用该框架,需设置
in 属性:要实现自动在div上增加类名,即通过in的值感知该div是入场状态还是出场状态
timeout 属性:动画执行时间
classNames :自定义的class名,注意是classNames
unMountOnExit :可选,当动画出场后在页面上移除包裹的dom节点
onEnter(onExit):入场(出场)动画第一帧自动执行
onEntering(onExiting):入场(出场)动画第二帧自动执行
onEntered (onExited):入场(出场)动画完成之后自动执行的钩子,接收一个参数,即插件内部的dom元素
*/}
<CSSTransition
in={this.state.show}
timeout={1000}
classNames='test'
unmountOnExit
onEntered={(el)=>{
el.style.color='red'
}}
>
<div>hello</div>
</CSSTransition>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
// 让show不断变换真值
handleToggle() {
this.setState({
show: this.state.show ? false : true
})
}
}
export default App;
xxx-enter: 进入(入场)前的CSS样式;
xxx-enter-active:进入动画直到完成时之前的CSS样式;
xxx-enter-done:进入完成时的CSS样式;
xxx-exit:退出(出场)前的CSS样式;
xxx-exit-active:退出动画直到完成时之前的的CSS样式。
xxx-exit-done:退出完成时的CSS样式。
/*test是自定义的类名,插件将会自动的在包裹住的标签上添加很多css样式,默认class名是fade*/
/*enter是入场前的刹那(点击按钮),appear指页面第一次加载前的一刹那(自动)*/
.test-enter, .test-appear {
opacity: 0;
}
/*enter-active指入场的第二个瞬间到入场结束之前的过程,appear-active则是页面第一次加载自动执行*/
.test-enter-active, .test-appear-active {
opacity: 1;
transition: opacity 1s ease-in;
}
/*入场动画执行完毕后,用于保持状态*/
.test-enter-done {
opacity: 1;
/*color: red; 也可以用js来实现,即onEntered钩子*/
}
/*出场前的第一刹那*/
.test-exit {
opacity: 1;
}
.test-exit-active {
opacity: 0;
transition: opacity 1s ease-in;
}
/*入场动画执行完毕后,用于保持状态*/
.test-exit-done {
opacity: 0;
}
项目地址:单个组件动画
3.多个组件的动画效果
使用TransitionGroup
,只需变动js文件
import React, {Component, Fragment} from 'react';
import { CSSTransition,TransitionGroup } from 'react-transition-group';
import './style.css'
class App extends Component {
constructor(props) {
super(props);
this.state = {
show: true,
list:[]
};
this.handleAddItem = this.handleAddItem.bind(this);
}
render() {
return (
<Fragment>
{/*所有组件外层包裹TransitionGroup*/}
<TransitionGroup>
{
// 这里注意map的参数第一个item是元素,第二个index是下标,注意顺序
this.state.list.map((item,index)=>{
return (
// 每个组件或元素包裹CSSTransition
<CSSTransition
key={index}
timeout={1000}
classNames='test'
unmountOnExit
onEntered={(el)=>{
el.style.color='red'
}}
>
<div >{item}</div>
</CSSTransition>
)
})
}
</TransitionGroup>
<button onClick={this.handleAddItem}>Add</button>
</Fragment>
)
}
//每点击一次便增加一个item
handleAddItem(){
this.setState((prevState)=>{
return{
list:[...prevState.list,'item']
}
})
}
}
export default App;
项目地址:多个组件动画