wo-user-part-uniapp/cToast/cToast.vue

277 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
based on
https://ext.dcloud.net.cn/plugin?id=672
https://github.com/steffenx/uniapp_popup
*数组形式传值
*type,类型 success warn info fail loadingstring默认info
*content,内容string
*duration,消失时间Number默认2000
*distance,弹窗间距默认128可设为0代表重叠
*isClick,是否点击消失Boolean默认false
-->
<template>
<view class="popup_list">
<view v-for="(items,index) of popup_list" :id="items.uuid" :key="items.uuid" >
<view class="mpopup" :style="{ background: items.color ,top:index*items.distance+50+'px'}" :class="[items.animator,items.typeClass]" @click="close(items.uuid,index)">
<view class="pic"><image class="icon" mode="aspectFit" :src="items.icon"></image></view>
<text class="text" :style="{ color: items.colortext }">{{ items.content }}</text>
</view>
</view>
</view>
</template>
<script>
export default{
data(){
return{
popup_list:[],//弹窗数组
}
},
props:{
},
methods:{
init:function(toast){
if (toast.type == 'success') {
toast.icon = toast.icon || '../static/cToast.success.png';
toast.typeClass='mpopup-success';
return toast;
}
if (toast.type == 'warn') {
toast.icon = toast.icon || '../static/cToast.warn.png';
toast.typeClass='mpopup-warn';
return toast;
}
if (toast.type == 'info') {
toast.icon = toast.icon || '../static/cToast.info.png';
toast.typeClass='mpopup-info';
return toast;
}
if (toast.type == 'fail') {
toast.icon = toast.icon || '../static/cToast.fail.png';
toast.typeClass='mpopup-fail';
return toast;
}
if (toast.type == 'loading') {
toast.icon = toast.icon || '../static/cToast.loading.png';
toast.typeClass='mpopup-loading';
return toast;
}
},
open:function(toast){
//生成uuid
let uuid=this.guid();
toast.uuid=uuid;
//添加动画
toast.animator='fade_Down';
toast.isClick = toast.isClick || false //判断是否可点击消失/可控制消失
toast.duration = toast.duration || 1500
toast.distance = toast.distance || 128 // 弹窗间距
toast.type = toast.type || 'info'
//初始化
let newToast=this.init(toast);
//添加进数组
this.popup_list.push(newToast);
if(!newToast.isClick){
this.disappear(newToast.uuid,newToast.duration);
}//可点击消失
else{
this.$emit('uuidCallback',newToast.uuid);
}
},
//自动消失
disappear:function(uuid,duration){
//退出动画之后,短暂延迟后移除本元素
this.fade_out_animator(uuid,duration).then(res=>{
setTimeout(()=>{
for(let i=0;i<this.popup_list.length;i++){
if(this.popup_list[i].uuid==res){
//移除本元素
this.popup_list.splice(i,1);
this.$forceUpdate()
}
}
},250)
});
},
fade_out_animator:function(uuid,duration){
//duration秒后退出
if(!duration||typeof(duration)!='number'){duration=1500;}
return new Promise(res=>{
setTimeout(()=>{
for(let i=0;i<this.popup_list.length;i++){
if(this.popup_list[i].uuid==uuid){
//添加退出动画
this.popup_list[i].animator='fade_Top';
res(uuid);
}
}
},duration)
})
},
//可控制关闭的弹出框
close:function(uuid,ind){
if(ind){
if(!this.popup_list[ind].isClick){return}
}
this.remove_element(uuid).then((res)=>{
setTimeout(()=>{
for(let i=0;i<this.popup_list.length;i++){
if(this.popup_list[i].uuid==res){
//移除本元素
this.popup_list.splice(i,1);
this.$emit('closeCallback',uuid);
this.$forceUpdate()
}
}
},250)
})
},
//控制移除元素
remove_element:function(uuid){
return new Promise(res=>{
for (var i = 0; i < this.popup_list.length; i++) {
if(this.popup_list[i].uuid==uuid){
this.popup_list[i].animator='fade_Top';
res(uuid)
break;
}
}
})
},
//更新
update:function(update_list){
for (var i = 0; i < this.popup_list.length; i++) {
if(this.popup_list[i].uuid==update_list.uuid){
this.popup_list[i].type=update_list.type;
this.init(this.popup_list[i]);
this.popup_list[i].content=update_list.content;
break;
}
}
},
//生成uuid
guid:function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
}
}
</script>
<style lang="scss">
.mpopup{
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
min-height: 45px;
max-width: 80%;
transition :all .5s;
position: fixed;
right:0;
left:0;
margin: 0 auto;
border-radius: 5px;
z-index:998;
@media screen and (min-width: 751px) { max-width: 500px }
.pic{
display: flex;
text-align: center;
justify-content: center;
width: 32px;
height: 32px;
margin: 20px;
.icon{
width: 100%;
height: auto;
}
}
.text{
margin: 0px 20px 20px 20px;
font-size: 16px;
}
}
.mpopup-success{
background: #f0f9eb;
border: 1px solid #e1f3d8;
color: #67c23a;
}
.mpopup-fail{
background: #fef0f0;
border: 1px solid #fde2e2;
color: #f56c6c;
}
.mpopup-warn{
background: #fdf6ec;
border: 1px solid #faecd8;
color: #e6a23c;
}
.mpopup-info{
background: #edf2fc;
border: 1px solid #ebeef5;
color: #909399;
}
.mpopup-loading{
background: #e2f5ff;
border: 1px solid #ceeeff;
color: #5cbaff;
image{
animation: rotate360 1.5s ease infinite;
}
}
.fade_Down{
animation: fadeInDown 0.6s both;
}
.fade_Top{
animation: fadeInTop 0.5s forwards;
}
/*从上到下*/
@keyframes fadeInDown
{
from {
opacity: 0;
-webkit-transform: translate(0,-100px);
transform: stranslate(0,-100px);
}
to {
opacity:1;
-webkit-transform: translate(0,10px);
transform: stranslate(0,10px);
}
}
/*从下到上*/
@keyframes fadeInTop
{
from {
opacity:1;
-webkit-transform: translate(0,10px);
transform: stranslate(0,10px);
}
to {
opacity: 0;
-webkit-transform: translate(0,-100px);
transform: stranslate(0,-100px);
}
}
@keyframes rotate360
{
from {
transform: rotate(0);
}
to{
transform: rotate(360deg);
}
}
</style>