问题

在单页面应用中,我们经常需要给路由的切换或者元素的挂载和卸载加上过渡效果,为这么一个小功能引入第三方框架,实在有点小纠结。不如自己封装。

思路

原理

以进入时opacity: 0 --> opacity: 1 ,退出时opacity: 0 --> opacity: 1为例

元素挂载时

  1. 挂载元素dom
  2. 设置动画opacity: 0 --> opacity: 1

元素卸载时

  1. 设置动画opacity: 0 --> opacity: 1
  2. 动画结束后卸载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组件,为组件进入和离开加上动画/过度的更多相关文章

  1. 放弃antd table,基于React手写一个虚拟滚动的表格

    缘起 标题有点夸张,并不是完全放弃antd-table,毕竟在react的生态圈里,对国人来说,比较好用的PC端组件库,也就antd了.即便经历了2018年圣诞彩蛋事件,antd的使用者也不仅不减,反 ...

  2. 手写一个简单的starter组件

    spring-boot中有很多第三方包,都封装成starter组件,在maven中引用后,启动springBoot项目时会自动装配到spring ioc容器中. 思考: 为什么我们springBoot ...

  3. 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能

    在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...

  4. Ionic 2 中创建一个照片倾斜浏览组件

    内容简介 今天介绍一个新的UI元素,就是当我们改变设备的方向时,我们可以看到照片的不同部分,有一种身临其境的感觉,类似于360全景视图在移动设备上的应用. 倾斜照片浏览 Ionic 2 实例开发 新增 ...

  5. Tsx写一个通用的button组件

    一年又要到年底了,vue3.0都已经出来了,我们也不能一直还停留在过去的js中,是时候学习并且在项目中使用一下Ts了. 如果说jsx是基于js的话,那么tsx就是基于typescript的 废话也不多 ...

  6. AngularJS中写一个包裹HTML元素的directive

    有这样的一个场景,这里有一个表单: <form role="form">    ...</form> 我们希望在form的外层动态包裹上一层. 有可能是这样 ...

  7. 在vue中写一个跟着鼠标跑的div,div里面动态显示数据

    1.div应该放在body里面,这是我放在body中的一个div里面的div <!-- 信息查看层 --> <div class="floatDiv" :styl ...

  8. 如何在react中实现一个倒计时组件

    倒计时组件 import React, { Component } from 'react' import $ from 'jquery' import "../../css/spellTE ...

  9. 如何在 React Native 中写一个自定义模块

    https://my.oschina.net/jpushtech/blog/983230

随机推荐

  1. css 文本属性和字体属性

    1.将浮动居中 这需要三个盒子 <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  2. 201871010125 王玉江 《面向对象程序设计(Java)》第八周实验总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  3. 微信小程序 - Request | 路由跳转 | 本地存储

    Request 官方文档 wx.request相当于发送ajax请求 参数 属性 类型 默认值 必填 说明 url string   是 开发者服务器接口地址 data string/object/A ...

  4. 残差residual VS 误差 error

    https://blog.csdn.net/jmydream/article/details/8764869 In statistics and optimization, statistical e ...

  5. Spring Cloud微服务安全实战_3-7_API安全之授权

    API安全之授权 访问控制: 1,ACL :Access Control Lists,直接给每个用户授权,他能访问什么.开发简单,但是用户多的话,给每个用户授权比较麻烦. 2,RBAC:Role Ba ...

  6. 微信小程序特性总结

    一. 小程序不是运行在浏览器中, 所以没有BOM和DOM对象 即console.log(window)和console.log(document)是获取不到任何内容的 二. 小程序特有的额外js成员( ...

  7. MACbook安装WIN7中文版后乱码的解决办法

    控制面板→时钟.语言和区域→区域和语言→管理→更改系统区域设置→选择为中国,简体中文→确定,按照要求你重启即可. 原来这个本子是香港买的,默认区域是英语,我说怎么乱码.

  8. [学习笔记] 网络最大流的HLPP算法

    #define \(u\)的伴点集合 与\(u\)相隔一条边的且\(u\)能达到的点的集合 \(0x00~ {}~Preface\) \(HLPP(Highest~Label~Preflow~Push ...

  9. Express服务器开发

    作者 | Jeskson 来源 | 达达前端小酒馆 Express服务器开发 创建Express应用程序,Express路由,pug视图模板的使用 Express简介: 让我们来创建Express应用 ...

  10. [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 ...