<template>
<view
class="u-toast"
:class="[isShow ? 'u-show' : '','u-position-' + config.position,config.icon?'has-icon':'']"
:style="{
zIndex: uZIndex
}"
>
<view class="u-icon-wrap">
<image src="/static/base-module/toast-icon/success.png" v-if="config.type==='success'&&config.icon" class="success icon"></image>
<image src="/static/base-module/toast-icon/warning.png" v-if="config.type==='warning'&&config.icon" class="warning icon"></image>
<image src="/static/base-module/toast-icon/error.png" v-if="config.type==='error'&&config.icon" class="error icon"></image>
<image src="/static/base-module/toast-icon/loading.png" v-if="config.type==='loading'&&config.icon" class="loading icon"></image>
</view>
<text class="u-text" :class="[config.icon?'icon-text':'']">{{config.title}}</text>
</view>
</template>
<script>
export default {
name: 'u-toast',
props: {
zIndex: {
type: [Number, String],
default: ''
}
},
data() {
return {
isShow: false,
timer: null,
config: {
params: {},
title: '',
type: '',
duration: 2000,
isTab: false,
url: '',
icon: false,
position: 'center',
callback: null,
back: false
}
}
},
computed: {
iconName() {
if (
['error', 'warning', 'success', 'info'].indexOf(this.config.type) >=
0 &&
this.config.icon
) {
let icon = this.$u.type2icon(this.config.type)
return icon
}
},
uZIndex() {
return this.isShow
? this.zIndex
? this.zIndex
: this.$u.zIndex.toast
: '999999'
}
},
methods: {
show(options) {
this.config = this.$u.deepMerge(this.config, options)
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
this.isShow = true
this.timer = setTimeout(() => {
this.isShow = false
clearTimeout(this.timer)
this.timer = null
typeof this.config.callback === 'function' && this.config.callback()
this.timeEnd()
}, this.config.duration)
},
hide() {
this.isShow = false
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
},
timeEnd() {
if (this.config.url) {
if (this.config.url[0] != '/') this.config.url = '/' + this.config.url
if (Object.keys(this.config.params).length) {
let query = ''
if (/.*\/.*\?.*=.*/.test(this.config.url)) {
query = this.$u.queryParams(this.config.params, false)
this.config.url = this.config.url + '&' + query
} else {
query = this.$u.queryParams(this.config.params)
this.config.url += query
}
}
if (this.config.isTab) {
uni.switchTab({
url: this.config.url
})
} else {
uni.navigateTo({
url: this.config.url
})
}
} else if (this.config.back) {
this.$u.route({
type: 'back'
})
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../../libs/css/style.components.scss';
.u-toast {
position: fixed;
z-index: -1;
transition: opacity 0.3s;
text-align: center;
color:rgba(255,255,255,1);
border-radius: rpx(88);
background:rgba(0,0,0,0.6);
min-height: rpx(120);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: rpx(40);
opacity: 0;
pointer-events: none;
padding: 0 rpx(60);
min-width: rpx(520);
max-width: rpx(1120);
}
.has-icon{
background:rgba(0,0,0,0.6);
border-radius:rpx(16);
min-width: rpx(490);
max-width: rpx(632);
word-wrap:break-word;
padding:rpx(90) rpx(30) rpx(96) rpx(30);
}
.u-toast.u-show {
opacity: 1;
}
.u-text {
word-wrap:break-word;
font-size:rpx(40);
color:rgba(255,255,255,1);
}
.icon-text{
font-size:rpx(46);
font-weight:400;
color:rgba(255,255,255,1);
word-wrap:break-word;
}
.u-icon {
margin-right: 5rpx;
display: flex;
align-items: center;
line-height: normal;
}
.icon{
width: rpx(172);
height: rpx(172);
margin-bottom: rpx(48);
}
.loading {
animation: loading 1s steps(8) infinite;
}
@keyframes loading {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
.u-position-center {
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
.u-position-top {
left: 50%;
top: 20%;
transform: translateX(-50%) translateY(-50%);
}
.u-position-bottom {
left: 50%;
bottom: 20%;
transform: translateX(-50%) translateY(-50%);
}
</style>