2025-12-08 18:17:12 +08:00

117 lines
2.5 KiB
Vue

<template>
<view v-if="visible" class="custom-toast" :style="{ animationDuration: duration + 'ms' }">
<view class="toast-content">
<view class="toast-icon">
<u-icon :name="icon" :color="iconColor" :size="iconSize"></u-icon>
</view>
<view class="toast-text">{{ text }}</view>
</view>
</view>
</template>
<script>
export default {
name: 'CustomToast',
data() {
return {
visible: false,
text: '添加成功',
icon: 'checkmark-circle-fill',
iconColor: '#4CD964',
iconSize: 60,
duration: 1000,
timer: null
}
},
methods: {
// 显示Toast
show(options = {}) {
const app = this
// 清除之前的定时器
if (app.timer) {
clearTimeout(app.timer)
app.timer = null
}
// 设置参数
app.text = options.text || '添加成功'
app.icon = options.icon || 'checkmark-circle-fill'
app.iconColor = options.iconColor || '#4CD964'
app.iconSize = options.iconSize || 60
app.duration = options.duration || 1000
// 显示Toast
app.visible = true
// 设置定时器自动隐藏
app.timer = setTimeout(() => {
app.hide()
}, app.duration)
},
// 隐藏Toast
hide() {
const app = this
app.visible = false
if (app.timer) {
clearTimeout(app.timer)
app.timer = null
}
}
}
}
</script>
<style lang="scss" scoped>
.custom-toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
pointer-events: none;
animation: fadeInOut 1s ease-in-out;
}
.toast-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.7);
border-radius: 16rpx;
padding: 40rpx 60rpx;
min-width: 200rpx;
}
.toast-icon {
margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.toast-text {
color: #fff;
font-size: 28rpx;
line-height: 1.5;
text-align: center;
}
@keyframes fadeInOut {
0% {
opacity: 0;
transform: translate(-50%, -50%) scale(0.8);
}
20% {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
80% {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
100% {
opacity: 0;
transform: translate(-50%, -50%) scale(0.8);
}
}
</style>