popup.vue消息提示组件

原文地址https://blog.phyer.cn/article/5296

分享一个使用vue单文件组件写的一个弹出提示消息的组件

效果

代码

popup.vue

<template>
    <div>
        <div :class="['ani', state]"
            @mouseenter="toggle_pause(true)"
            @mouseleave="toggle_pause(false)"
        >
            <div class="bg"></div>
            <div class="show">
                <span></span>
                <a>{{msg}}</a>
            </div>
            <span @click="close"></span>
            <div class="process"></div>
        </div>
    </div>
</template>

<script>
import $ from 'jQuery';
window.$ = $;
window.jQuery = $;
import '../../../static/js_lib/velocity.min';

export default {
    data (){
        return {
            state: 'suc',
            msg: '无消息',
            // 弹出/隐藏 延迟和动画
            pop_delay: 300,
            pop_easing: 'ease-out',
            // 展示时间
            duration: 3000,
        }
    },
    methods: {
        show (data){
            let vue_ = this;
            // 更改信息
            this.msg = data.msg;
            this.state = data.state;
            let poper = this.$el.querySelector('.ani'),
                timer = this.$el.querySelector('.process');
            // 重置popup和timing状态
            $(poper).velocity('stop', true);
            $(timer).velocity('stop', true);
            $(poper).velocity({left: '100%'}, 0, ()=>{
                $(timer).velocity({left: '0'}, 0, ()=>{
                   // 开始弹出动画
                    $(poper).velocity({left: '0'}, vue_.pop_delay, vue_.pop_easing,
                        ()=>{
                            // 开始计时动画
                            $(timer).velocity({left: '-100%'}, vue_.duration, 'linear',
                                ()=>{
                                    // 开始收回动画
                                    $(poper).velocity({left: '100%'}, vue_.pop_delay, vue_.pop_easing,
                                        ()=>{
                                            // 计时器归零
                                            timer.style.left = '0';
                                        }
                                    )
                                }
                            )
                        }
                    )
                });
            });
        },
        close (){
            let vue_ = this,
                poper = this.$el.querySelector('.ani'),
                timer = this.$el.querySelector('.process');
            // 停止动画
            $(poper).velocity('stop', true);
            $(timer).velocity('stop', true);
            // 开始隐藏动画
            timer.style.left = '0';
            $(poper).velocity({left: '100%'}, vue_.pop_delay, vue_.pop_easing, ()=>{
                timer.style.left = '0'
            })
        },
        toggle_pause (b){
            let timer = this.$el.querySelector('.process');
            if (b){
                $(timer).velocity('pause');
            }else{
                $(timer).velocity('resume');
            }
        }
    }
}
</script>

<style lang="scss">
    #popup{
        max-width: 50%;
        position: fixed;
        right: 0;
        top: 0;
        >.ani{
            border-radius: 0.4rem 0.4rem 0 0;
            box-shadow: 0 0 0.6rem rgba(0, 0, 0, 0.4);
            padding: 1rem 2rem;
            margin: 1rem;
            overflow: hidden;
            position: relative;
            left: 100%;
            >.bg{
                width: 100%;
                height: 100%;
                border-radius: inherit;
                z-index: 1;
                position: absolute;
                left: 0;
                top: 0;
            }
            >.show{
                z-index: 2;
                border-radius: inherit;
                >span{
                    &:before{
                        font-family: var(--iconfont);
                        font-size: 1.4rem;
                        margin-right: 1rem;
                    }
                }
                >a{
                    font-size: 0.8rem;
                    line-height: 1.2rem;
                }
            }
            @each $cls,$col,$f in (warn, #ffe99a, #ffb100), (suc, #b5ffca, #5478ff), (err, #ffc4ba, #ff0012){
                &.#{$cls}{
                    >.bg{
                        background: $col;
                    }
                    >.show >span:before{
                        color: $f;
                        content: var(--i-#{$cls});
                    }
                }
            }
            >span{
                position: absolute;
                top: 0.3rem;
                right: 0.3rem;
                line-height: 0.7rem;
                cursor: pointer;
                color: #666;
                z-index: 2;
                &:before{
                    font-family: var(--iconfont);
                    content: var(--i-close);
                    font-size: 0.6rem;
                }
                &:hover{
                    color: red;
                    font-weight: bold;
                }
            }
            >.process{
                width: 100%;
                height: 0.2rem;
                background: #c300ff;
                position: absolute;
                bottom: 0;
                left: 0;
                z-index: 2;
            }
        }
    }
</style>

util.js

  import popup from '../../components/popup/popup.vue';
    window.header_vue = new Vue({
        el: '#popup',
        data: {
        },
        components: {popup},
        methods: {
            pop_data (data) {
                this.$refs.popup.show(data)
            }
        }
    });

在使用的地方只需要这样写:

... ...
header_vue.pop_data({state: 'suc', msg: '成功'})
... ....
上一篇:简单封装一个下弹框


下一篇:重写简易的confirm函数