Files
dygou_go/frontend/src/components/ToastContainer.vue
T
2026-06-26 10:56:25 +08:00

115 lines
1.9 KiB
Vue

<script setup lang="ts">
import { useToast } from '@/composables/useToast'
const { toasts, removeToast } = useToast()
</script>
<template>
<div class="toast-container" :class="{ show: toasts.length > 0 }">
<TransitionGroup name="toast">
<div
v-for="toast in toasts"
:key="toast.id"
class="toast"
:class="`toast-${toast.type}`"
@click="removeToast(toast.id)"
>
<div class="toast-title">{{ toast.title }}</div>
<div class="toast-body" v-html="toast.body"></div>
</div>
</TransitionGroup>
</div>
</template>
<style scoped>
.toast-container {
position: fixed;
top: 20px;
right: -420px;
z-index: 9999;
transition: right .35s cubic-bezier(.16, 1, .3, 1);
}
.toast-container.show {
right: 20px;
}
.toast {
background: var(--surface);
border: 1px solid var(--line);
border-left-width: 3px;
border-radius: var(--radius);
padding: 12px 14px;
margin-bottom: 8px;
min-width: 300px;
max-width: 380px;
box-shadow: var(--shadow);
cursor: pointer;
transition: opacity .3s, transform .3s;
}
.toast-title {
font-size: 12.5px;
font-weight: 600;
margin-bottom: 3px;
color: var(--text-strong);
}
.toast-body {
font-size: 12px;
color: var(--muted);
line-height: 1.6;
}
.toast-success {
border-left-color: var(--success);
}
.toast-success .toast-title {
color: var(--success);
}
.toast-info {
border-left-color: var(--accent);
}
.toast-info .toast-title {
color: var(--accent);
}
.toast-warn {
border-left-color: var(--warning);
}
.toast-warn .toast-title {
color: var(--warning);
}
.toast-error {
border-left-color: var(--danger);
}
.toast-error .toast-title {
color: var(--danger);
}
/* 动画 */
.toast-enter-active {
transition: all .3s ease;
}
.toast-leave-active {
transition: all .3s ease;
}
.toast-enter-from {
opacity: 0;
transform: translateX(30px);
}
.toast-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>