在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 相关文章推荐
return false,对阻止事件默认动作的一些测试代码
Nov 17 Javascript
jquery实现点击文字可编辑并修改保存至数据库
Apr 15 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
Dec 13 Javascript
js判断浏览器是否支持严格模式的方法
Oct 04 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
Dec 26 Javascript
JavaScript实现自定义媒体播放器方法介绍
Jan 03 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
Jan 16 Javascript
jQuery实现按比例缩放图片的方法
Apr 29 jQuery
微信小程序实现流程进度的图样式功能
Jan 16 Javascript
JavaScript数据结构之栈实例用法
Jan 18 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
Nov 12 Javascript
详解jQuery的核心函数和事件处理
Feb 18 jQuery
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编写批量生成不重复的卡号密码代码
2015/05/14 PHP
php计算整个目录大小的方法
2015/06/19 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
PHP中非常有用却鲜有人知的函数集锦
2019/08/17 PHP
php实现多站点共用session实现单点登录的方法详解
2019/09/18 PHP
JQuery 图片延迟加载并等比缩放插件
2009/11/09 Javascript
javascript中字符串替换函数replace()方法与c# 、vb 替换有一点不同
2010/06/25 Javascript
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
node.js实现多图片上传实例
2014/06/03 Javascript
nodejs教程之异步I/O
2014/11/21 NodeJs
jQuery仿360导航页图标拖动排序效果代码分享
2015/08/24 Javascript
利用 spin.js 生成等待效果(js 等待效果)
2017/06/25 Javascript
利用javascript如何随机生成一定位数的密码
2017/09/22 Javascript
javaScript手机号码校验工具类PhoneUtils详解
2017/12/08 Javascript
JS实现的判断方法、变量是否存在功能示例
2020/03/28 Javascript
Python3计算三角形的面积代码
2017/12/18 Python
python中文乱码不着急,先看懂字节和字符
2017/12/20 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
使用Python写一个小游戏
2018/04/02 Python
Python模拟百度自动输入搜索功能的实例
2019/02/14 Python
python并发编程多进程之守护进程原理解析
2019/08/20 Python
Pyinstaller加密打包应用的示例代码
2020/06/11 Python
python实现测试工具(一)——命令行发送get请求
2020/10/19 Python
爱淘宝:淘宝网购物分享平台
2017/04/28 全球购物
Skyscanner澳大利亚:全球领先的旅游搜索网站
2018/03/24 全球购物
贝斯特韦斯特酒店集团官网:Best Western
2019/01/03 全球购物
大学毕业生文采飞扬的自我鉴定
2013/12/03 职场文书
便利店的创业计划书
2014/01/15 职场文书
物业经理自我鉴定
2014/03/03 职场文书
就业推荐表自我鉴定范文
2014/03/21 职场文书
化学专业自荐信
2014/05/28 职场文书
法人代表任命书范本
2014/06/05 职场文书
中学教师教学工作总结
2015/08/13 职场文书
2016幼儿园毕业感言
2015/12/08 职场文书
创业计划书之便利店
2019/09/05 职场文书
Python re.sub 反向引用的实现
2021/07/07 Python