在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 相关文章推荐
jQuery图片滚动图片的效果(另类实现)
Jun 02 Javascript
For循环中分号隔开的3部分的执行顺序探讨
May 27 Javascript
JavaScript动态插入CSS的方法
Dec 10 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
Nov 22 Javascript
微信小程序之选项卡的实现方法
Sep 29 Javascript
js实现数组内数据的上移和下移的实例
Nov 14 Javascript
Javascript网页抢红包外挂实现分享
Jan 11 Javascript
全新打包工具parcel零配置vue开发脚手架
Jan 11 Javascript
小程序开发基础之view视图容器
Aug 21 Javascript
详解vue配置后台接口方式
Mar 29 Javascript
vue列表数据发生变化指令没有更新问题及解决方法
Jan 16 Javascript
详解如何修改 node_modules 里的文件
May 22 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实现多服务器共享SESSION数据的方法
2007/03/16 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
Yii2 queue的队列使用详解
2019/07/19 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
2021/03/09 PHP
javascript 触发HTML元素绑定的函数
2010/09/11 Javascript
Bootstrap教程JS插件滚动监听学习笔记分享
2016/05/18 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
vue项目中使用scss的方法步骤
2019/05/16 Javascript
Vue中 axios delete请求参数操作
2020/08/25 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
Python3读取文件常用方法实例分析
2015/05/22 Python
Python fileinput模块使用实例
2015/05/28 Python
python制作小说爬虫实录
2017/08/14 Python
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
Django + Uwsgi + Nginx 实现生产环境部署的方法
2018/06/20 Python
Python 生成 -1~1 之间的随机数矩阵方法
2018/08/04 Python
ipython和python区别详解
2019/06/26 Python
python实现代码统计器
2019/09/19 Python
pytorch中的卷积和池化计算方式详解
2020/01/03 Python
Python3 实现爬取网站下所有URL方式
2020/01/16 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
win7上tensorflow2.2.0安装成功 引用DLL load failed时找不到指定模块 tensorflow has no attribute xxx 解决方法
2020/05/20 Python
纯css3实现的竖形无限级导航
2014/12/10 HTML / CSS
Willer台湾:日本高速巴士/夜行巴士预约
2017/07/09 全球购物
澳大利亚最早和最古老的巨型游戏专家:Yardgames
2020/02/20 全球购物
Vinatis德国:法国领先的葡萄酒邮购公司
2020/09/07 全球购物
应届生保险求职信
2013/11/11 职场文书
计算机科学系职业生涯规划书
2014/03/08 职场文书
农村产权制度改革实施方案
2014/03/21 职场文书
先进个人评语大全
2015/01/04 职场文书
幼儿园六一主持词
2015/06/30 职场文书
庆七一晚会主持词
2015/06/30 职场文书
《曹冲称象》教学反思
2016/02/20 职场文书
python图片灰度化处理的几种方法
2021/06/23 Python