How to make a small notification plugin in Vue

Vue

How to make a small notification plugin in Vue

Notifications are a great way to let the user know about the status of his actions on the website. For example, on a cms, we would have options to create, update, delete various records.

It would be cool to pop some notification on the screen after one of these actions executes. Our goal is to create a reusable piece of code that we can bring to any Vue project.

I will create a simple index component with buttons to test our notification plugin. I will reuse Laravel welcome page.

<div id="app">
    <div class="container-fluid">
        <div class="row">
            <index-component></index-component>
        </div>
    </div>
</div>


I also have to include js and CSS in my head.

<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">

<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>


I will rename ExampleComponent to IndexComponent and add some buttons with empty methods for now.

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Index Component</div>

                    <div class="card-body">
                        <button @click="successNotification" class="btn btn-sm btn-success">Success</button>
                        <button @click="warningNotification" class="btn btn-sm btn-warning">Warning</button>
                        <button @click="infoNotification" class="btn btn-sm btn-info">Info</button>
                        <button @click="dangerNotification" class="btn btn-sm btn-danger">Danger</button>
                   </div>

                </div>
            </div>
        </div>
</div>
</template>
<script>
export default {
        methods: {
            successNotification() { },
            warningNotification() { },
            infoNotification() { },
            dangerNotification() { }
        }
    }
</script>

 

Now we can start working on our notification plugin. Plugins in Vue are a great option for adding some global functionality to Vue applications.

For example, a notification plugin. Vue Router is also a good example of a Vue plugin.

Aside from creating a good name, we also need to expose the install method from our plugin. Install method will be called with the Vue constructor as the first argument and additional options that can customize the behavior of the plugin as the second argument.

This is the starting point of a Vue plugin.

export default {
  install (Vue, options) {
    //
  }
}


I will call it a "notifier". Seems appropriate enough. Let's create a plugins folder inside resources/js and create a notifier folder. Inside the notifier, we will create two files and a CSS folder for styles.


In index.js we will have all our logic of how to create a new notification. Here, we will expose the install method for the Vue constructor. Our plugin will work like this.

We call this.$notifier with one of the four properties available. From there, we will create a constructor for the Notifier component with Vue.extend(), merge all passed options, and finally create a new instance of Notifier.

import Notifier from './Notifier';
import './css/styles.css';

const NotifierVue = {

    // Expose install method
    install(Vue, options) {

         // Construct a new Notification component

         function createNotifier(obj, type) {const NotificationComponent = Vue.extend(Notifier);
            let title, message;

            // Set default title and message

            switch(type){case 'success':
                    title = 'Success Message';
                    message = 'Action was successful';
                    break;
                case 'error':
                    title = 'Error Message';
                    message = 'Action was unsuccessful';
                    break;
                case 'info':
                    title = 'Info Message';
                    message = 'Action was successful';
                    break;
                case 'warning':
                    title = 'Warning Message';
                    message = 'Action requires your attention';
                    break;
            }

            let defaultTitleMessage = {
                title: title,
                message: message
            };

            // Merge all present options

            let props = Object.assign(defaultTitleMessage, options, obj, { type : type });return new NotificationComponent({
                el: document.createElement('div'),
                propsData: props
            });
        }

        // Add Vue instance methods which will create appropriate notifier
        Vue.prototype.$notifier = {
            success(obj) {
                return createNotifier(obj, 'success');
            },
            error(obj) {
                return createNotifier(obj, 'error');
            },
            warning(obj) {
                return createNotifier(obj, 'warning');
            },
            info(obj) {
                return createNotifier(obj, 'info');
            }
        }
    }
};

export default NotifierVue;


In Notifier.vue component we will have our markup code for the notification. We have four props. Title, message or body, type, and duration of notification.

Our notifier will be able to display a single or an array of messages, such as, for example, you get with validation errors. In beforeMount() method it will check if the notification container already exists, otherwise, it will create a new one.

After it is mounted, it will wait for the duration to expires upon which it will destroy itself.

<template>
    <div v-if="show" :class="'notify-'+type" class="notifier notifier-shadow"><p>{{ title }}</p><p class="object-message"v-if="typeof message === 'array'" v-for="text in message"
        >
            {{ text }}
        </p><p v-else>{{ message }}</p></div>
</template>
<script>export default {
        props: {
            title: {
                type: String
            },
            message: {
                type: [String, Array]
            },
            type: {
                type: String
            },
            duration: {
                type: Number,
                default: 2000
            },
        },
        data() {
            return {
                show: true
            }
        },
        beforeMount() {
            // Look for notification containerlet container = document.getElementById('notification-container');

            // If not found create new container and append to body
            if (!container) {
                container = document.createElement('div');
                container.id = 'notification-container';
                document.body.append(container);
            }

            // Append notification to container
            container.appendChild(this.$el);
        },
        mounted() {
            // Destroy notification after specified duration timelet self = this;
            setTimeout(()=>{
                self.show = !self.show;
                self.destroyNotifier();
            }, this.duration);
        },
        methods: {
            destroyNotifier(){
                setTimeout(()=>{
                    this.$destroy();
                }, 500);
            }
        }
    }
</script>


In style.css we have notifier styles. Nothing here that requires explaining.

#notification-container{
    z-index: 9999;
    padding: 10px;
    position: fixed;
    top: 0;
    right: 0;
}

.notifier{
    margin-bottom: 10px;
    width: auto;
    height: auto;
    padding: 7px 100px 0 10px;
    border-radius: 5px;
}

.notifier > p:nth-child(1){
    color: #fff;
    font-size: 1.15rem;
    margin-bottom: 2.5px;
}

.notifier > p:nth-child(2){
    color: #fff;
    margin: 0;
    padding: 0 0 5px 0;
}

.notifier-shadow{
    box-shadow: 0 3px 5px rgba(0, 0, 0, 0.4);
}

.notifier:hover{
    cursor: pointer
}

.notify-success{
    background-color: rgba(40, 167, 69, 0.95) !important;
}
.notify-error{
    background-color: rgba(220, 53, 69, 1) !important;
}
.notify-warning{
    background-color: rgba(255, 193, 7, 1) !important;
}
.notify-info{
    background-color: rgba(23, 162, 184, 1) !important;
}

.object-message {
    color: #fff;
    margin: 0;
    padding: 0 0 5px 0;
}


Let's update our Index Component methods. This is an example of how you would call our notifier.

export default {
    methods: {
        successNotification() {
            this.$notifier.success({
                title: 'Success',
                message: 'Success button clicked',
                duration: 2000
            });
        },
        warningNotification() {
            this.$notifier.warning({
                title: 'Warning',
                message: 'Warning button clicked',
                duration: 2000
            });
        },
        infoNotification() {
            this.$notifier.info({
                title: 'Info',
                message: 'Info button clicked',
                duration: 2000
            });
        },
        dangerNotification() {
            this.$notifier.error({
                title: 'Danger',
                message: 'Danger button clicked',
                duration: 2000
            });
        }
    }
}


The only thing left to do is to register our plugin

// Vue Notifier
import VueNotifier from './plugins/notifier/index';
Vue.use(VueNotifier);

 

This is the final look of our notifier.


You can easily modify this plugin to your heart's desire by adding additional props and passable options. From position, styles, message handlers, etc.

Show comments

Laravel

5 min

How to make Laravel authentication

Laravel provides a neat function that quickly generates a scaffold of routes, views, and controllers used for authentication.

Laravel

7 min

How to install Laravel application

This article will cover how to install and create a local development environment for your Laravel application. There are only a couple of steps that needs to be done.

Laravel

3 min

How to set appropriate Laravel permissions on Linux server

After publishing your Laravel application to a real web server, you discover then some of your functionalities are failing.

Codinary