在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 相关文章推荐
优化网页之快速的呈现我们的网页
Jun 29 Javascript
JQUERY 浏览器判断实现函数
Aug 20 Javascript
javascript oop开发滑动(slide)菜单控件
Aug 25 Javascript
javascript中的delete使用详解
Apr 11 Javascript
javascript:;与javascript:void(0)使用介绍
Jun 05 Javascript
一个html5播放视频的video控件只支持android的默认格式mp4和3gp
May 08 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
详解javascript数组去重问题
Nov 06 Javascript
分享js粘帖屏幕截图到web页面插件screenshot-paste
Aug 21 Javascript
js实现select二级联动下拉菜单
Apr 17 Javascript
vue+Java后端进行调试时解决跨域问题的方式
Oct 19 Javascript
浅谈KOA2 Restful方式路由初探
Mar 14 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代码技巧的小结
2013/06/02 PHP
php+ajax实现无刷新分页
2015/11/18 PHP
ThinkPHP下表单令牌错误与解决方法分析
2017/05/20 PHP
PHP按一定比例压缩图片的方法
2018/10/12 PHP
php实例化一个类的具体方法
2019/09/19 PHP
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
Javascript 继承机制的实现
2009/08/12 Javascript
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
2则自己编写的jQuery特效分享
2015/02/26 Javascript
jQuery实现锚点scoll效果实例分析
2015/03/10 Javascript
jQuery在ul中显示某个li索引号的方法
2015/03/17 Javascript
12行javascript代码绘制一个八卦图
2015/04/02 Javascript
原生js实现移动端瀑布流式代码示例
2015/12/18 Javascript
js智能获取浏览器版本UA信息的方法
2016/08/08 Javascript
解析NodeJS异步I/O的实现
2017/04/13 NodeJs
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
2017/05/17 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
node.js的Express服务器基本使用教程
2019/01/09 Javascript
[02:38]DOTA2亚洲邀请赛 IG战队巡礼
2015/02/03 DOTA
Python实现的Google IP 可用性检测脚本
2015/04/23 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
Python生成器以及应用实例解析
2018/02/08 Python
PyCharm代码提示忽略大小写设置方法
2018/10/28 Python
Python实现八皇后问题示例代码
2018/12/09 Python
python 自动重连wifi windows的方法
2018/12/18 Python
python3 os进行嵌套操作的实例讲解
2020/11/19 Python
CSS3的Border-radius轻松制作圆角
2012/12/24 HTML / CSS
荷兰鞋子在线:Nelson Schoenen
2017/12/25 全球购物
医学院学生求职简历的自我评价
2013/10/24 职场文书
解除合同协议书范本
2016/03/21 职场文书
mybatis使用oracle进行添加数据的方法
2021/04/27 Oracle
在python中实现导入一个需要传参的模块
2021/05/12 Python
pytorch实现手写数字图片识别
2021/05/20 Python