Implementation Preview
Component Overview
Notification components of this type are typically invoked directly within JavaScript code, similar to this example:
this.$notification('Stop clicking, you have reached the end!')
How ever, most implementations found online utilize the component approach, requiring manual placement of component elements in the DOM and controlling visibility through variables. This creates unnecessary complexity. A more elegant solution involves using Vue.extend to create components that can be called direct without DOM manipulation. This approach requires two files: a .vue file for the template and a management .js file.
Implementation Code
Toast.vue component implementation:
<template>
<div class="notification" v-show="isActive">
{{ notificationText }}
</div>
</template>
<script>
export default {
name: 'notification',
data() {
return {
notificationText: '',
displayDuration: 3000,
isDismissed: false,
countdownTimer: null,
isActive: false
}
},
mounted() {
this.initCountdown()
},
watch: {
isDismissed(newStatus) {
if (newStatus) {
this.isActive = false
this.cleanupDOM()
}
}
},
methods: {
cleanupDOM() {
this.$destroy()
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el)
}
},
initCountdown() {
this.countdownTimer = setTimeout(() => {
if (!this.isDismissed) {
this.isDismissed = true
clearTimeout(this.countdownTimer)
}
}, this.displayDuration)
}
}
}
</script>
<style lang="scss" scoped>
.notification {
position: fixed;
top: 75vh;
right: 30vw;
min-width: 35vw;
max-width: 95vw;
font-size: 28px;
text-align: center;
padding: 15px 3vw;
border-radius: 35px;
background-color: rgba(30, 30, 30, 0.7);
color: #f0f0f0;
letter-spacing: 2px;
}
</style>
Toast.js management file:
import Vue from 'vue'
import NotificationComponent from '@/components/ui/Notification.vue'
const NotificationConstructor = Vue.extend(NotificationComponent)
let currentInstance
let counter = 1
const createNotification = (config = {}) => {
if (typeof config === 'string') {
config = {
notificationText: config
}
}
const uniqueId = `notification_${counter++}`
currentInstance = new NotificationConstructor({
data: config
})
currentInstance.identifier = uniqueId
currentInstance.componentRef = currentInstance.$mount()
document.body.appendChild(currentInstance.componentRef.$el)
currentInstance.componentRef.isActive = true
currentInstance.elementRef = currentInstance.componentRef.$el
currentInstance.elementRef.style.zIndex = 1000 + counter
return currentInstance.componentRef
}
export default createNotification
Usage Instructions
First, import the Toast.js file in main.js and attach it to the Vue prototype:
import notificationService from './path/to/Toast.js'
Vue.prototype.$toast = notificationService
Then use the component in you're code:
this.$toast('Stop clicking, you have reached the end!')