原文地址 https://blog.phyer.cn/article…
分享一个使用 vue 单文件组件写的一个弹出提示消息的组件
效果
Edge 下的测试
演示视频
代码
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: '成功'})
... ...
velocityjs
此组件的动画基于 velocityjs,它是一个兼容性较强,性能强和可自定义的前端动画框架,有兴趣可以了解一下。