在react里面添加动画效果大多都使用react-transition-group这个库
react-transition-group主要包含四个组件
Transition
1.该组件是一个和平台无关的组件(不一定要结合css)
2.在前端开发中,我们一般是结合css来完成样式,所以比较常用的是CSSTransition
CSSTransition
1.在前端开发中,通常使用CSSTransition来完成过渡动画效果
SwitchTransition
1.两个组件显示和隐藏切换时,使用该组件
TransitionGroup
1.将多个动画组件包裹在其中,一般用于列表中元素的动画
下面就来演示一下CSSTransition,SwitchTransition,TransitionGroup这三个案例
首先
yarn add react-transition-group
CSSTransition
我这个案例用了antd这个ui库,充当一下内容
yarn add antd
yarn add @ant-design/icons
找个入口文件导入一下样式
import 'antd/dist/antd.css'
创建一个CSSTransition.js文件
import React, { PureComponent } from 'react'
import {CSSTransition} from 'react-transition-group'
import './CSSTransition.css'
import { Card, Avatar } from 'antd';
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
const { Meta } = Card;
export default class cSSTransition extends PureComponent {
constructor(props){
super(props);
this.state={
isShow:true
}
}
render() {
const {isShow} =this.state
return (
<div>
<button onClick={e=>{this.setState({isShow:!isShow})}}>显示/隐藏</button>
<CSSTransition in={isShow}
classNames="card"
timeout={300}
unmountOnExit={true}
appear
onEnter={el =>console.log('开始进入')}
onEntering={el =>console.log('正在进入')}
onEntered={el =>console.log('进入完成')}
onExit={el =>console.log('开始退出')}
onExiting={el =>console.log('退出状态')}
onExited={el =>console.log('退出完成')}>
<Card
style={{ width: 300 }}
cover={
<img
alt="example"
src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
/>
}
actions={[
<SettingOutlined key="setting" />,
<EditOutlined key="edit" />,
<EllipsisOutlined key="ellipsis" />,
]}
>
<Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title="Card title"
description="This is the description"
/>
</Card>
</CSSTransition>
</div>
)
}
}
点击切换之后就会有淡入淡出效果
in是看显示还是隐藏
timeout是控制类名添加/移除的时间
unmountOnExit是否在原文档中
appear内容为true,第一次渲染的时候也加动画,还要添加css属性
onEnter,onExit这些是生命周期钩子
还得有css样式才行,创建一个CSSTransition.css
注意:
CSSTransition执行过程中,有三种状态:appear,enter,exit
它们有三种状态,需要定义对应的CSS样式
第一类,开始状态:对应的类是-appear,-enter,exit
第二类,执行动画:对应的类是-appear-active,-enter-active,-exit-active
第三类,执行结束:对应的类是-appear-done,-enter-done,-exit-done
.card-enter, .card-appear{
opacity: 0;
transform: scale(.6);
}
.card-enter-active, .card-appear-active{
opacity: 1;
transform: scale(1);
transition: opacity 300ms,transform 300ms;
}
.card-enter-done, .card-appear-done{
}
.card-exit{
opacity: 1;
transform: scale(1);
}
.card-exit-active{
opacity: 0;
transform: scale(.6);
transition: opacity 300ms,transform 300ms;
}
.card-exit-done{
opacity: 0;
}
SwitchTransition
SwitchTransition可以完成两个组件之间切换的炫酷动画
1.比如我们有一个按钮需要在on和off之间切换,我们希望看到on先从左侧退出,off再从右侧进入
2.这个动画在vue中被称为vue transition modes
3.react-transition-group中使用SwitchTransition来实现该动画
SwitchTransition中主要有一个属性:mode ,有两个值
1.in-out:表示新组件先进入,旧组件再移除
2.out-in:表示旧组件先移除,新组件再进入
创建一个SwitchTransition.js文件
import React, { PureComponent } from 'react'
import {SwitchTransition, CSSTransition} from 'react-transition-group'
import './SwitchTransition.css'
export default class switchTransition extends PureComponent {
constructor(props){
super(props)
this.state={
isOn:true
}
}
render() {
const {isOn} = this.state
return (
<div>
<SwitchTransition>
<CSSTransition key={isOn?"on":"off"}
classNames="btn"
timeout={300}>
<button onClick={e=>this.setState({isOn:!isOn})}>{isOn?"on":"off"}</button>
</CSSTransition>
</SwitchTransition>
</div>
)
}
}
创建一个SwitchTransition.css
.btn-enter{
opacity: 0;
transform: translateX(100%);
}
.btn-enter-active{
opacity: 1;
transform: translateX(0);
transition: opacity 300ms,transform 300ms;
}
.btn-exit{
opacity: 1;
transform: translateX(0);
}
.btn-exit-active{
opacity: 0;
transform: translateX(-100%);
transition: opacity 300ms,transform 300ms;
}
TransitionGroup
创建一个TransitionGroup.js文件
import React, { PureComponent } from 'react'
import {CSSTransition,TransitionGroup} from 'react-transition-group'
import './TransitionGroup.css'
export default class transitionGroup extends PureComponent {
constructor(props){
super(props);
this.state={
names:['kobe','james','jorden']
}
}
render() {
return (
<TransitionGroup>
{
this.state.names.map((item,index)=>{
return (
<CSSTransition key={index}
timeout={500}
classNames="item">
<p>{item}</p>
</CSSTransition>
)
})
}
<button onClick={e=>this.addname()}>+name</button>
</TransitionGroup>
)
}
addname(){
this.setState({
names:[...this.state.names,'lsh']
})
}
}
创建一个TransitionGroup.css文件
.item-enter{
opacity: 0;
transform: translateX(100%);
}
.item-enter-active{
opacity: 1;
transform: translateX(0);
transition: opacity 300ms,transform 300ms;
}
.item-enter-done{
color: red;
}
.item-exit{
opacity: 1;
transform: translateX(0);
}
.item-exit-active{
opacity: 0;
transform: translateX(-100%);
transition: opacity 300ms,transform 300ms;
}
.item-exit-done{
opacity: 0;
}