在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 相关文章推荐
jBox 2.3基于jquery的最新多功能对话框插件 常见使用问题解答
Nov 10 Javascript
解析Node.js异常处理中domain模块的使用方法
Feb 16 Javascript
JavaScript数组操作函数汇总
Aug 05 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
Sep 14 Javascript
js 实现一些跨浏览器的事件方法详解及实例
Oct 27 Javascript
js实现日历与定时器
Feb 22 Javascript
详解Vue 非父子组件通信方法(非Vuex)
May 24 Javascript
vue使用nprogress实现进度条
Dec 09 Javascript
vue中提示$index is not defined错误的解决方式
Sep 02 Javascript
JS绘图Flot如何实现可选显示曲线图功能
Oct 16 Javascript
Vue ​v-model相关知识总结
Jan 28 Vue.js
JavaScript 生成唯一ID的几种方式
Feb 19 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读取大文件末尾N行的高效方法推荐
2016/06/03 PHP
var与Javascript变量隐式声明
2009/09/17 Javascript
JQuery实现的在新窗口打开链接的方法小结
2010/04/22 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
JS解决url传值出现中文乱码的另类办法
2013/04/08 Javascript
jQuery动态添加、删除元素的方法
2014/01/09 Javascript
jQuery循环滚动新闻列表示例代码
2014/06/17 Javascript
[原创]推荐10款最热门jQuery UI框架
2014/08/19 Javascript
12行javascript代码绘制一个八卦图
2015/04/02 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
2015/04/02 Javascript
JS实现星星评分功能实例代码(两种方法)
2016/06/09 Javascript
js重写方法的简单实现
2016/07/10 Javascript
ReactNative Image组件使用详解
2017/08/07 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
2018/04/11 jQuery
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
如何使用CSS3和JQuery easing 插件制作绚丽菜单
2019/06/18 jQuery
多页vue应用的单页面打包方法(内含打包模式的应用)
2020/06/11 Javascript
Javascript数组及类数组相关原理详解
2020/10/29 Javascript
python搭建简易服务器分析与实现
2012/12/15 Python
在python中的socket模块使用代理实例
2014/05/29 Python
Python素数检测的方法
2015/05/11 Python
好用的Python编辑器WingIDE的使用经验总结
2016/08/31 Python
python实现根据文件关键字进行切分为多个文件的示例
2018/12/10 Python
pytorch GAN生成对抗网络实例
2020/01/10 Python
一些关于python 装饰器的个人理解
2020/08/31 Python
使用CSS3和Checkbox实现JQuery的一些效果
2015/08/03 HTML / CSS
全球性的奢侈品梦工厂:Forzieri(福喜利)
2019/02/20 全球购物
英国马莎百货印度官网:Marks & Spencer印度
2020/10/08 全球购物
医学生自我鉴定范文
2013/11/08 职场文书
学雷锋活动总结报告
2014/06/26 职场文书
民族学专业大学生职业规划范文:清晰未来的构想
2014/09/20 职场文书
实训报告范文大全
2014/11/04 职场文书
Ajax实现局部刷新的方法实例
2021/03/31 Javascript
36个正则表达式(开发效率提高80%)
2021/11/17 Javascript
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
2022/04/11 Python
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers