| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- <template>
- <div class="notification-container">
- <img src="@/assets/images/notification.png" alt="" class="warning-icon" />
- <div v-if="notifications.length > 0" class="notification-content">
- <el-carousel
- ref="carousel"
- height="30px"
- direction="vertical"
- indicator-position="none"
- :autoplay="true"
- :interval="5000"
- @change="updateCurrentIndex"
- >
- <el-carousel-item
- v-for="notification in notifications"
- :key="notification.id"
- class="notification-item"
- @click="handleClick(notification)"
- >
- <span class="title">{{ notification.title }}</span>
- <span>{{ notification.time }}</span>
- </el-carousel-item>
- </el-carousel>
- </div>
- <div v-if="notifications.length > 0" class="arrow-controls">
- <button class="custom-arrow up" :disabled="currentIndex === 0" @click="scrollUp">
- <span class="arrow"></span>
- </button>
- <button class="custom-arrow down" :disabled="currentIndex === notifications.length - 1" @click="scrollDown">
- <span class="arrow"></span>
- </button>
- </div>
- <div v-else class="no-notifications">
- <p>暂无通知</p>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { ref } from 'vue';
- export interface Notification {
- id: number;
- title: string;
- time: string;
- }
- defineProps<{ notifications: Notification[] }>();
- const emit = defineEmits<{
- (e: 'remove-notification', id: number): void;
- }>();
- const carousel = ref<HTMLFormElement>();
- const currentIndex = ref(0);
- const updateCurrentIndex = (current: number) => {
- currentIndex.value = current;
- };
- const scrollUp = () => {
- currentIndex.value--;
- carousel.value?.setActiveItem(currentIndex.value);
- };
- const scrollDown = () => {
- currentIndex.value++;
- carousel.value?.setActiveItem(currentIndex.value);
- };
- const handleClick = (notification: Notification) => {
- emit('remove-notification', notification.id);
- };
- </script>
- <style scoped lang="scss">
- .notification-container {
- width: 100%;
- height: 30px;
- display: flex;
- align-items: center;
- overflow: hidden;
- }
- .warning-icon {
- width: 14px;
- height: 14px;
- margin: 0 13px;
- }
- .notification-content {
- width: 100%;
- line-height: 38px;
- .notification-item {
- display: flex;
- align-items: center;
- font-size: 14px;
- color: rgba(0, 0, 0, 0.88);
- cursor: pointer;
- .title {
- margin-right: 30px;
- }
- }
- }
- .arrow-controls {
- display: flex;
- flex-direction: column;
- margin-left: auto;
- margin-right: 10px;
- .custom-arrow {
- width: 18px;
- height: 18px;
- background: #fffbe6;
- border: none;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.3s ease;
- }
- .arrow {
- display: inline-block;
- width: 0;
- height: 0;
- border-style: solid;
- border-width: 6px 7px 10px 7px;
- border-color: transparent transparent #fae697 transparent;
- transition: all 0.2s ease;
- }
- .custom-arrow.down .arrow {
- transform: rotate(180deg);
- }
- .custom-arrow:hover {
- .arrow {
- border-color: transparent transparent #faad14 transparent;
- }
- }
- .custom-arrow[disabled] {
- opacity: 0.4;
- cursor: not-allowed;
- .arrow {
- border-color: transparent transparent #fae697 transparent;
- }
- }
- }
- .no-notifications {
- font-size: 14px;
- color: rgba(0, 0, 0, 0.88);
- }
- </style>
|