时间:2021-07-01 10:21:17 帮助过:16人阅读
问题
在单页面应用中,我们经常需要给路由的切换或者元素的挂载和卸载加上过渡效果,为这么一个小功能引入第三方框架,实在有点小纠结。不如自己封装。
思路
原理
以进入时 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组件为组件进入和离开加上动画/过度效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!