共计 2840 个字符,预计需要花费 8 分钟才能阅读完成。
原文地址 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,它是一个兼容性较强,性能强和可自定义的前端动画框架,有兴趣可以了解一下。
正文完
发表至: javascript
2020-06-25