Creating Toast Components in Vue Using Vue.extend Pattern

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!')

Tags: vue Component Toast vue-extend javascript

Posted on Sun, 09 Aug 2026 16:37:50 +0000 by rakennedy75