国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

在React中寫一個Animation組件為組件進(jìn)入和離開加上動畫/過度效果

2024-05-06 16:52:39
字體:
供稿:網(wǎng)友

在React中寫一個Animation組件為組件進(jìn)入和離開加上動畫/過度效果

問題

在單頁面應(yīng)用中,我們經(jīng)常需要給路由的切換或者元素的掛載和卸載加上過渡效果,為這么一個小功能引入第三方框架,實(shí)在有點(diǎn)小糾結(jié)。不如自己封裝。

思路

原理

以進(jìn)入時 opacity: 0 --> opacity: 1  ,退出時 opacity: 0 --> opacity: 1 為例

元素掛載時

1.掛載元素dom
2.設(shè)置動畫 opacity: 0 --> opacity: 1

元素卸載時

1.設(shè)置動畫 opacity: 0 --> opacity: 1 
2.動畫結(jié)束后卸載dom

組件設(shè)計(jì)

為了使得組件簡單易用、低耦合,我們期望如下方式來調(diào)用組件:

在 App.jsx 里調(diào)用組件:

通過改變isShow的值來指定是否顯示

// App.jsx
// 其他代碼省略
import './app.css';
<Animation isShow={isShow} name='demo'>
    <div class='demo'>
        demo
    </div>
</Animation>
// 通過改變isShow的值來指定是否顯示
在 App.css 里指定進(jìn)入離開效果:
// 基礎(chǔ)樣式
.demo {
    width: 200px;
    height: 200px;
    background-color: red;
}
// 定義進(jìn)出入動畫
.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;
    }
}

根據(jù)思路寫代碼

// 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示例

點(diǎn)我直達(dá)


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 亳州市| 汝州市| 阿瓦提县| 贡觉县| 山阳县| 玛多县| 长乐市| 新和县| 兴义市| 桑植县| 清水河县| 海丰县| 山西省| 化州市| 格尔木市| 阿勒泰市| 砚山县| 邛崃市| 蓝山县| 昭平县| 建始县| 迁西县| 渭南市| 荣昌县| 诏安县| 尖扎县| 唐河县| 博野县| 安仁县| 望江县| 堆龙德庆县| 通许县| 镇康县| 察隅县| 兴和县| 元江| 沾化县| 博乐市| 确山县| 纳雍县| 大余县|