在React中写一个Animation组件为组件进入和离开加上动画/过度效果


Posted in Javascript onJune 24, 2019

问题

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

思路

原理

以进入时 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组件为组件进入和离开加上动画/过度效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
javascript while语句和do while语句的区别分析
Dec 08 Javascript
javascript for循环设法提高性能
Feb 24 Javascript
基于socket.io和node.js搭建即时通信系统
Jul 30 Javascript
jQuery抛物线运动实现方法(附完整demo源码下载)
Jan 08 Javascript
一篇文章掌握RequireJS常用知识
Jan 26 Javascript
微信小程序  action-sheet详解及实例代码
Nov 09 Javascript
bootstrap实现动态进度条效果
Mar 08 Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 Javascript
JavaScript输入分钟、秒倒计时技巧总结(附代码)
Aug 17 Javascript
老生常谈JS中的继承及实现代码
Jul 06 Javascript
vue实现select下拉显示隐藏功能
Sep 30 Javascript
Javascript var变量删除原理及实现
Aug 26 Javascript
node中实现删除目录的几种方法
Jun 24 #Javascript
什么时候不能在 Node.js 中使用 Lock Files
Jun 24 #Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
Jun 24 #Javascript
浅谈一个webpack构建速度优化误区
Jun 24 #Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
Jun 24 #Javascript
Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
Jun 24 #Javascript
JavaScript学习教程之cookie与webstorage
Jun 23 #Javascript
You might like
PHP 文件上传进度条的两种实现方法的代码
2007/11/25 PHP
PHP计算百度地图两个GPS坐标之间距离的方法
2015/01/09 PHP
Windows7下的php环境配置教程
2015/02/28 PHP
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
PHP的mysqli_select_db()函数讲解
2019/01/23 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
jQuery获得指定元素坐标的方法
2015/04/14 Javascript
jQuery Validate初步体验(一)
2015/12/12 Javascript
JavaScript数组的定义及数字操作技巧
2016/06/06 Javascript
AngularJS基础 ng-open 指令简单实例
2016/08/02 Javascript
JS类的定义与使用方法深入探索
2016/11/26 Javascript
修改UA在PC中访问只能在微信中打开的链接方法
2017/11/27 Javascript
js实现轮播图的完整代码
2020/10/26 Javascript
解决Js先触发失去焦点事件再执行点击事件的问题
2018/08/30 Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
[15:20]DOTA2-DPC中国联赛 正赛 Elephant vs Aster 选手采访
2021/03/11 DOTA
python中文编码问题小结
2014/09/28 Python
Python连接MySQL并使用fetchall()方法过滤特殊字符
2016/03/13 Python
简单学习Python time模块
2016/04/29 Python
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
PyCharm+PySpark远程调试的环境配置的方法
2018/11/29 Python
python3.x实现base64加密和解密
2019/03/28 Python
Python Web框架之Django框架Form组件用法详解
2019/08/16 Python
深入了解python列表(LIST)
2020/06/08 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
2020/06/10 Python
pandas.DataFrame.drop_duplicates 用法介绍
2020/07/06 Python
洲际酒店集团大中华区:IHG中国
2016/08/17 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
先进事迹报告会主持词
2014/04/02 职场文书
学术诚信承诺书
2014/05/26 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
干部作风建设个人剖析材料
2014/10/11 职场文书
乡镇计划生育工作汇报
2014/10/28 职场文书
2014年卫生监督工作总结
2014/12/09 职场文书
民警忠诚教育心得体会
2016/01/23 职场文书
SQL Server远程连接的设置步骤(图文)
2022/03/23 SQL Server