在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 相关文章推荐
childNodes.length与children.length的区别
May 14 Javascript
Prototype源码浅析 String部分(一)之有关indexOf优化
Jan 15 Javascript
JS仿百度搜索自动提示框匹配查询功能
Nov 21 Javascript
jquery实现的一个简单进度条效果实例
May 12 Javascript
node.js中的querystring.unescape方法使用说明
Dec 10 Javascript
微信WeixinJSBridge API使用实例
May 25 Javascript
JavaScript实现给按钮加上双重动作的方法
Aug 14 Javascript
JavaScript实现给定时间相加天数的方法
Jan 25 Javascript
JS中的BOM应用
Feb 02 Javascript
解决Vue.js父组件$on无法监听子组件$emit触发事件的问题
Sep 12 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
Oct 28 Javascript
js实现弹出框的拖拽效果实例代码详解
Apr 16 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字符串截取函数用法分析
2014/11/25 PHP
PHP大神的十大优良习惯
2016/09/14 PHP
解析 thinkphp 框架中的部分方法
2017/05/07 PHP
Laravel中为什么不使用blpop取队列详析
2018/08/01 PHP
用javascript编写的第一人称射击游戏
2007/02/25 Javascript
JAVASCRIPT IE 与 FF中兼容问题小结
2009/02/18 Javascript
瀑布流布局并自动加载实现代码
2013/03/12 Javascript
正负小数点后两位浮点数实现原理及代码
2013/09/06 Javascript
深入理解JS中的变量及作用域、undefined与null
2014/03/04 Javascript
对之前写的jquery分页做下升级
2014/06/19 Javascript
JQuery 在线引用及测试引用是否成功
2014/06/24 Javascript
jquery利用拖拽方式在图片上添加热链接
2015/11/24 Javascript
javascript设计模式--策略模式之输入验证
2015/11/27 Javascript
浏览器复制插件zeroclipboard使用指南
2016/03/26 Javascript
第一次动手实现bootstrap table分页效果
2016/09/22 Javascript
JS实现的驼峰式和连字符式转换功能分析
2016/12/21 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
JS获取子节点、父节点和兄弟节点的方法实例总结
2018/07/06 Javascript
js实现动态增加文件域表单功能
2018/10/22 Javascript
微信小程序之swiper滑动面板用法示例
2018/12/04 Javascript
vue解决花括号数据绑定不成功的问题
2019/10/30 Javascript
[49:11]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第二场 12.20
2020/12/23 DOTA
Python在图片中插入大量文字并且自动换行
2019/01/02 Python
Python玩转PDF的各种骚操作
2019/05/06 Python
python 协程 gevent原理与用法分析
2019/11/22 Python
Python文件操作基础流程解析
2020/03/19 Python
django教程如何自学
2020/07/31 Python
香港现代设计家具品牌:Ziinlife Furniture
2018/11/13 全球购物
房地产财务管理制度
2014/02/02 职场文书
红领巾广播站广播稿
2014/10/19 职场文书
幼儿园园长新年寄语2015
2014/12/08 职场文书
租车协议书
2015/01/27 职场文书
八年级数学教学反思
2016/02/17 职场文书
初三化学教学反思
2016/02/22 职场文书
新手必备之MySQL msi版本下载安装图文详细教程
2021/05/21 MySQL