Notification.vue 1.77 KB
Newer Older
wanli's avatar
wanli committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
<template>
        <div class="fm-notification">
            <transition-group name="notify">
                <div class="fm-notification-item" role="alert"
                     v-for="(notification, index) in notifications"
                     v-bind:class="`fm-${notification.status}`"
                     v-bind:key="`notify-${index}`">
                    {{ notification.message }}
                </div>
            </transition-group>
        </div>
</template>

<script>
import EventBus from '@/utils/eventBus';

export default {
  name: 'notification',
  data() {
    return {
      notifications: [],
    };
  },
  mounted() {
    /**
     * Listen 'addNotification' events
     */
    EventBus.$on('addNotification', ({ status, message }) => this.addNotification(status, message));
  },
  methods: {
    /**
     * Show new notification
     * @param status
     * @param message
     */
    addNotification(status, message) {
      this.notifications.push({
        status, message,
      });
      // timeout for closing
      setTimeout(() => {
        this.notifications.shift();
      }, 3000);
    },
  },
};
</script>

<style lang="scss">
    .fm-notification {
        position: absolute;
        right: 1rem;
        bottom: 0;
        z-index: 9999;
        width: 350px;
        display: block;
        transition: opacity .4s ease;
        overflow: auto;

        .fm-notification-item {
            padding: .75rem 1.25rem;
            margin-bottom: 1rem;
            border: 1px solid;
            border-radius: .25rem;
        }

        .notify-enter-active {
            transition: all .3s ease;
        }
        .notify-leave-active {
            transition: all .8s ease;
        }
        .notify-enter, .notify-leave-to {
            opacity: 0;
        }
    }
</style>