planet/src/components/global/Notification.vue
huangjinming 356ce606f1 fix
2023-08-18 10:19:42 +08:00

120 lines
2.1 KiB
Vue

<template>
<transition-group name="slide" tag="div">
<div
v-for="(notification, index) in notifications"
:key="notification.id"
class="notification"
:class="position"
>
<span>{{ notification.message }}</span>
</div>
</transition-group>
</template>
<script setup>
import { ref, reactive, onMounted, watchEffect } from "vue";
let id = 0;
const props = defineProps({
position: {
type: String,
default: "top-right",
validator: (value) =>
["top-right", "top-left", "bottom-right", "bottom-left"].includes(value),
},
duration: {
type: Number,
default: 3000,
},
});
const notifications = reactive([]);
const addNotification = (message) => {
const notification = {
id: id++,
message,
};
notifications.push(notification);
setTimeout(() => {
closeNotification(notifications.indexOf(notification));
}, props.duration);
};
const closeNotification = (index) => {
if (index !== -1) {
notifications.splice(index, 1);
}
};
defineExpose({
addNotification,
closeNotification,
});
</script>
<style lang="scss" scoped>
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s ease-out, opacity 0.3s ease-out;
}
.slide-enter-from,
.slide-leave-to {
transform: translateX(100%);
opacity: 0;
}
.slide-enter-to,
.slide-leave-from {
transform: translateX(0);
opacity: 1;
}
.notification {
position: fixed;
padding: 0.8em;
background: url('../../assets/img/task/msg-bg.png') no-repeat;
background-size: 100% 100%;
color: #721c24;
/* border: solid 1px #f5c6cb; */
border-radius: 0.25rem;
min-width: 304px;
min-height: 80px; /* set minimum height */
display: flex;
font-size: 14px;
font-family: Arial;
font-weight: 400;
color: #ffffff;
align-items: center;
justify-content: center;
text-align: center;
white-space: normal;
word-wrap: break-word;
}
.notification.top-right {
right: 50px;
top: 80px;
}
.notification.top-left {
left: 0;
top: 0;
}
.notification.bottom-right {
right: 0;
bottom: 0;
}
.notification.bottom-left {
left: 0;
bottom: 0;
}
</style>