在React中写一个Animation组件,为组件进入和离开加上动画/过度
问题
在单页面应用中,我们经常需要给路由的切换或者元素的挂载和卸载加上过渡效果,为这么一个小功能引入第三方框架,实在有点小纠结。不如自己封装。
思路
原理
以进入时opacity: 0 --> opacity: 1 ,退出时opacity: 0 --> opacity: 1为例
元素挂载时
- 挂载元素dom
- 设置动画
opacity: 0 --> opacity: 1
元素卸载时
- 设置动画
opacity: 0 --> opacity: 1 - 动画结束后卸载dom
组件设计
为了使得组件简单易用、低耦合,我们期望如下方式来调用组件:
| 属性名 | 类型 | 描述 |
|---|---|---|
| isShow | Boolean | 子元素显示或隐藏控制 |
| name | String | 指定一个name,动画进入退出时的动画 |
在App.jsx里调用组件:
通过改变isShow的值来指定是否显示
// App.jsx
// 其他代码省略
import './app.css';
<Animation isShow={isShow} name='demo'>
<div class='demo'>
demo
</div>
</Animation>
// 通过改变isShow的值来指定是否显示
在App.css里指定进入离开效果:
// 基础样式
.demo {
width: 200px;
height: 200px;
background-color: red;
}
// 定义进出入动画
.demo-showing {
animation: show 0.5s forwards;
}
.demo-fading {
animation: fade 0.5s forwards;
}
// 定义动画fade与show
@keyframes show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fade {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
根据思路写代码
// Animation.jsx
import { PureComponent } from 'react';
import './index.css';
class Animation extends PureComponent {
constructor(props) {
super(props);
this.state = {
isInnerShow: false,
animationClass: '',
};
}
componentWillReceiveProps(props) {
const { isShow } = props;
if (isShow) {
// 显示
this.show().then(() => {
this.doShowAnimation();
});
} else {
// 隐藏
this.doFadeAnimation();
}
}
handleAnimationEnd() {
const isFading = this.state.animationClass === this.className('fading');
if (isFading) {
this.hide();
}
}
show() {
return new Promise(resolve => {
this.setState(
{
isInnerShow: true,
},
() => {
resolve();
}
);
});
}
hide() {
this.setState({
isInnerShow: false,
});
}
doShowAnimation() {
this.setState({
animationClass: this.className('showing'),
});
}
doFadeAnimation() {
this.setState({
animationClass: this.className('fading'),
});
}
/**
* 获取className
* @param {string} inner 'showing' | 'fading'
*/
className(inner) {
const { name } = this.props;
if (!name) throw new Error('animation name must be assigned');
return `${name}-${inner}`;
}
render() {
let { children } = this.props;
children = React.Children.only(children);
const { isInnerShow, animationClass } = this.state;
const element = {
...children,
props: {
...children.props,
className: `${children.props.className} ${animationClass}`,
onAnimationEnd: this.handleAnimationEnd.bind(this),
},
};
return isInnerShow && element;
}
}
export default Animation;
Demo示例
在React中写一个Animation组件,为组件进入和离开加上动画/过度的更多相关文章
- 放弃antd table,基于React手写一个虚拟滚动的表格
缘起 标题有点夸张,并不是完全放弃antd-table,毕竟在react的生态圈里,对国人来说,比较好用的PC端组件库,也就antd了.即便经历了2018年圣诞彩蛋事件,antd的使用者也不仅不减,反 ...
- 手写一个简单的starter组件
spring-boot中有很多第三方包,都封装成starter组件,在maven中引用后,启动springBoot项目时会自动装配到spring ioc容器中. 思考: 为什么我们springBoot ...
- 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能
在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...
- Ionic 2 中创建一个照片倾斜浏览组件
内容简介 今天介绍一个新的UI元素,就是当我们改变设备的方向时,我们可以看到照片的不同部分,有一种身临其境的感觉,类似于360全景视图在移动设备上的应用. 倾斜照片浏览 Ionic 2 实例开发 新增 ...
- Tsx写一个通用的button组件
一年又要到年底了,vue3.0都已经出来了,我们也不能一直还停留在过去的js中,是时候学习并且在项目中使用一下Ts了. 如果说jsx是基于js的话,那么tsx就是基于typescript的 废话也不多 ...
- AngularJS中写一个包裹HTML元素的directive
有这样的一个场景,这里有一个表单: <form role="form"> ...</form> 我们希望在form的外层动态包裹上一层. 有可能是这样 ...
- 在vue中写一个跟着鼠标跑的div,div里面动态显示数据
1.div应该放在body里面,这是我放在body中的一个div里面的div <!-- 信息查看层 --> <div class="floatDiv" :styl ...
- 如何在react中实现一个倒计时组件
倒计时组件 import React, { Component } from 'react' import $ from 'jquery' import "../../css/spellTE ...
- 如何在 React Native 中写一个自定义模块
https://my.oschina.net/jpushtech/blog/983230
随机推荐
- css 文本属性和字体属性
1.将浮动居中 这需要三个盒子 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- 201871010125 王玉江 《面向对象程序设计(Java)》第八周实验总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- 微信小程序 - Request | 路由跳转 | 本地存储
Request 官方文档 wx.request相当于发送ajax请求 参数 属性 类型 默认值 必填 说明 url string 是 开发者服务器接口地址 data string/object/A ...
- 残差residual VS 误差 error
https://blog.csdn.net/jmydream/article/details/8764869 In statistics and optimization, statistical e ...
- Spring Cloud微服务安全实战_3-7_API安全之授权
API安全之授权 访问控制: 1,ACL :Access Control Lists,直接给每个用户授权,他能访问什么.开发简单,但是用户多的话,给每个用户授权比较麻烦. 2,RBAC:Role Ba ...
- 微信小程序特性总结
一. 小程序不是运行在浏览器中, 所以没有BOM和DOM对象 即console.log(window)和console.log(document)是获取不到任何内容的 二. 小程序特有的额外js成员( ...
- MACbook安装WIN7中文版后乱码的解决办法
控制面板→时钟.语言和区域→区域和语言→管理→更改系统区域设置→选择为中国,简体中文→确定,按照要求你重启即可. 原来这个本子是香港买的,默认区域是英语,我说怎么乱码.
- [学习笔记] 网络最大流的HLPP算法
#define \(u\)的伴点集合 与\(u\)相隔一条边的且\(u\)能达到的点的集合 \(0x00~ {}~Preface\) \(HLPP(Highest~Label~Preflow~Push ...
- Express服务器开发
作者 | Jeskson 来源 | 达达前端小酒馆 Express服务器开发 创建Express应用程序,Express路由,pug视图模板的使用 Express简介: 让我们来创建Express应用 ...
- [LeetCode] 554. Brick Wall 砖头墙壁
There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The b ...