在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学习笔记(九) js对象 设计模式
Jun 19 Javascript
javascript文件中引用依赖的js文件的方法
Mar 17 Javascript
JQuery 在线引用及测试引用是否成功
Jun 24 Javascript
JavaScript拆分字符串时产生空字符的解决方案
Sep 26 Javascript
Javascript基础教程之break和continue语句
Jan 18 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
Sep 01 Javascript
Javascript中字符串相关常用的使用方法总结
Mar 13 Javascript
妙用Angularjs实现表格按指定列排序
Jun 23 Javascript
详解react-webpack2-热模块替换[HMR]
Aug 03 Javascript
浅析node应用的timing-attack安全漏洞
Feb 28 Javascript
vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解
May 28 Javascript
浅谈webpack 四个核心概念之Entry
Jun 12 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/04/12 PHP
提高PHP性能的编码技巧以及性能优化详细解析
2013/08/24 PHP
PHP结合JQueryJcrop实现图片裁切实例详解
2014/07/24 PHP
举例详解PHP脚本的测试方法
2015/08/05 PHP
详解php 使用Callable Closure强制指定回调类型
2017/10/26 PHP
javascript自启动函数的问题探讨
2013/10/05 Javascript
javascript判断并获取注册表中可信任站点的方法
2015/06/01 Javascript
jQuery UI结合Ajax创建可定制的Web界面
2016/06/22 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
详解React 在服务端渲染的实现
2017/11/16 Javascript
Node.js学习教程之Module模块
2019/09/03 Javascript
vue  elementUI 表单嵌套验证的实例代码
2019/11/06 Javascript
Vue列表如何实现滚动到指定位置样式改变效果
2020/05/09 Javascript
微信小程序实现弹框效果
2020/05/26 Javascript
vue 动态给每个页面添加title、关键词和描述的方法
2020/08/28 Javascript
python 算法 排序实现快速排序
2012/06/05 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
Pandas中把dataframe转成array的方法
2018/04/13 Python
Python中super函数用法实例分析
2019/03/18 Python
pyqt5实现登录界面的模板
2020/05/30 Python
Python 实现毫秒级淘宝抢购脚本的示例代码
2019/09/16 Python
通过python检测字符串的字母
2020/02/18 Python
学会python自动收发邮件 代替你问候女友
2020/05/20 Python
浅谈python opencv对图像颜色通道进行加减操作溢出
2020/06/03 Python
用python写一个带有gui界面的密码生成器
2020/11/06 Python
python 实现围棋游戏(纯tkinter gui)
2020/11/13 Python
python用分数表示矩阵的方法实例
2021/01/11 Python
军训心得体会
2013/12/31 职场文书
关于廉洁的广播稿
2014/01/30 职场文书
网上卖盒饭创业计划书范文
2014/02/07 职场文书
学校食堂食品安全责任书
2014/07/28 职场文书
做一个有道德的人活动方案
2014/08/25 职场文书
期中考试复习计划
2015/01/19 职场文书
试用期转正工作总结2015
2015/05/28 职场文书
工作总结之小学教师体育工作范文(3篇)
2019/10/07 职场文书
详解NodeJS模块化
2021/06/15 NodeJs