在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 相关文章推荐
漂亮的jquery提示效果(仿腾讯弹出层)
Feb 05 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
Oct 29 Javascript
js实现基于正则表达式的轻量提示插件
Aug 29 Javascript
JSP基于Bootstrap分页显示实例解析
Jun 12 Javascript
BootStrap学习系列之Bootstrap Typeahead 组件实现百度下拉效果(续)
Jul 07 Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
Jan 30 Javascript
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
May 22 Javascript
js实现的格式化数字和金额功能简单示例
Jul 30 Javascript
JS严格模式原理与用法实例分析
Apr 27 Javascript
关于vue3默认把所有onSomething当作v-on事件绑定的思考
May 15 Javascript
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 Vue.js
Vant+postcss-pxtorem 实现浏览器适配功能
Feb 05 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+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
来自chinaz的ajax获取评论代码
2008/05/03 Javascript
验证码按回车不变解决方法
2013/03/29 Javascript
在Node.js应用中使用Redis的方法简介
2015/06/24 Javascript
全面解析Bootstrap表单使用方法(表单控件)
2015/11/24 Javascript
jQuery图片渐变特效的简单实现
2016/06/25 Javascript
JavaScript 字符串常用操作小结(非常实用)
2016/11/30 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
2017/02/14 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
html中通过JS获取JSON数据并加载的方法
2017/11/30 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
常见的浏览器存储方式(cookie、localStorage、sessionStorage)
2019/05/07 Javascript
JS实现点星星消除小游戏
2020/03/24 Javascript
python使用urllib2模块获取gravatar头像实例
2013/12/18 Python
解决Python出现_warn_unsafe_extraction问题的方法
2016/03/24 Python
浅谈Python 对象内存占用
2016/07/15 Python
Python中循环引用(import)失败的解决方法
2018/04/22 Python
python实现微信小程序自动回复
2018/09/10 Python
python 二维数组90度旋转的方法
2019/01/28 Python
python django下载大的csv文件实现方法分析
2019/07/19 Python
python爬虫 Pyppeteer使用方法解析
2019/09/28 Python
python 实现视频 图像帧提取
2019/12/10 Python
django数据模型(Model)的字段类型解析
2019/12/25 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
Python用来做Web开发的优势有哪些
2020/08/05 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
CSS的pointer-events属性详细介绍(作用和注意事项)
2014/04/23 HTML / CSS
选购国际女性时装设计师品牌:IFCHIC(支持中文)
2018/04/12 全球购物
美国室内和室外装饰花盆购物网站:ePlanters
2019/03/22 全球购物
旅游个人求职信范文
2014/01/30 职场文书
舞蹈比赛获奖感言
2014/02/04 职场文书
水电施工员岗位职责
2015/04/11 职场文书
大学三好学生主要事迹范文
2015/11/03 职场文书
MySQL磁盘碎片整理实例演示
2022/04/03 MySQL
TS 类型收窄教程示例详解
2022/09/23 Javascript