在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 相关文章推荐
js+FSO遍历文件夹下文件并显示
Mar 07 Javascript
教您去掉ie网页加载进度条的方法
Dec 09 Javascript
javascript控制swfObject应用介绍
Nov 29 Javascript
js处理json以及字符串的比较等常用操作
Sep 08 Javascript
对比分析json及XML
Nov 28 Javascript
jquery实现的判断倒计时是否结束代码
Feb 05 Javascript
简单的分页代码js实现
May 17 Javascript
解决Jstree 选中父节点时被禁用的子节点也会选中的问题
Dec 27 Javascript
Windows上node.js的多版本管理工具用法实例分析
Nov 06 Javascript
vue-router 2.0 跳转之router.push()用法说明
Aug 12 Javascript
JavaScript 空间坐标的使用
Aug 19 Javascript
JavaScript ES6的函数拓展
Jan 18 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
《Re:从零开始的异世界生活 冰结之绊》
2020/04/09 日漫
php实现的遍历文件夹下所有文件,编辑删除
2010/01/05 PHP
ecshop 批量上传(加入自定义属性)
2012/03/20 PHP
基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)
2013/06/25 PHP
PHP中的traits实现代码复用使用实例
2015/05/13 PHP
PHP实现删除字符串中任何字符的函数
2015/08/11 PHP
PHP的运行机制与原理(底层)
2015/11/16 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
Laravel框架实现定时Task Scheduling例子
2019/10/22 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
jquery在IE、FF浏览器的差别详细探讨
2013/04/28 Javascript
Bootstrap 附加导航(Affix)插件实例详解
2016/06/01 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
微信小程序上传图片到服务器实例代码
2017/11/07 Javascript
详解如何在vue项目中引入elementUI组件
2018/02/11 Javascript
NodeJS服务器实现gzip压缩的示例代码
2018/10/12 NodeJs
详解Vue组件之作用域插槽
2018/11/22 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
js实现录音上传功能
2019/11/22 Javascript
js实现随机点名器精简版
2020/06/29 Javascript
Nuxt.js的路由跳转操作(页面跳转nuxt-link)
2020/11/06 Javascript
nodejs处理tcp连接的核心流程
2021/02/26 NodeJs
Python中os和shutil模块实用方法集锦
2014/05/13 Python
Python判断字符串是否为字母或者数字(浮点数)的多种方法
2018/08/03 Python
python 中的9个实用技巧,助你提高开发效率
2020/08/30 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
Bealls Florida百货商店:生活服饰、家居装饰和鞋子
2018/02/23 全球购物
美国领先的低折扣旅行网站:Hotwire
2019/01/19 全球购物
请假条的格式
2014/04/11 职场文书
学校安全生产月活动总结
2014/07/05 职场文书
关于读书的演讲稿600字
2014/08/27 职场文书
护士自我推荐信范文
2015/03/24 职场文书
2015学校图书管理员工作总结
2015/05/11 职场文书
唤醒紫霞仙子,携手再游三界!大话手游X《大话西游》电影合作专属剧情任务
2022/04/03 其他游戏
台式电脑蓝牙适配器怎么安装?台式电脑蓝牙适配器安装教程
2022/04/08 数码科技
Android移动应用开发指南之六种布局详解
2022/09/23 Java/Android