In NOVA LAB, every station system is an independent module. Let's see how to create plugins that are truly useful: toast notifications and i18n (internationalization).
A toast is a short notification displayed temporarily. The plugin will provide a
show() method available throughout the entire application:1const ToastPlugin = {
2 install(app, options = {}) {
3 const duration = options.duration || 3000
4 const position = options.position || 'top-right'
5
6 const toasts = ref([])
7 let toastId = 0
8
9 const toast = {
10 show(message, type = 'info') {
11 const id = toastId++
12 toasts.value.push({ id, message, type })
13 setTimeout(() => {
14 toasts.value = toasts.value.filter(t => t.id !== id)
15 }, duration)
16 },
17 success(msg) { this.show(msg, 'success') },
18 error(msg) { this.show(msg, 'error') },
19 warning(msg) { this.show(msg, 'warning') },
20 list: toasts
21 }
22
23 app.provide('toast', toast)
24 }
25}Usage in a component:
1<script setup>
2import { inject } from 'vue'
3
4const toast = inject('toast')
5
6function onSave() {
7 toast.success('Data saved!')
8}
9
10function onError() {
11 toast.error('Satellite connection error!')
12}
13</script>A plugin for translating texts into different languages:
1const I18nPlugin = {
2 install(app, options) {
3 const locale = ref(options.defaultLocale || 'pl')
4 const messages = options.messages || {}
5
6 function t(key) {
7 const keys = key.split('.')
8 let result = messages[locale.value]
9 for (const k of keys) {
10 result = result?.[k]
11 }
12 return result || key
13 }
14
15 function setLocale(lang) {
16 if (messages[lang]) {
17 locale.value = lang
18 }
19 }
20
21 app.provide('i18n', {
22 t,
23 locale,
24 setLocale,
25 availableLocales: Object.keys(messages)
26 })
27
28 app.directive('t', (el, binding) => {
29 el.textContent = t(binding.value)
30 })
31 }
32}Usage:
1app.use(I18nPlugin, {
2 defaultLocale: 'pl',
3 messages: {
4 pl: {
5 nav: { home: 'Strona główna', settings: 'Ustawienia' },
6 status: { online: 'Połączony', offline: 'Rozłączony' }
7 },
8 en: {
9 nav: { home: 'Home', settings: 'Settings' },
10 status: { online: 'Connected', offline: 'Disconnected' }
11 }
12 }
13})In a component:
1<script setup>
2import { inject } from 'vue'
3const { t, setLocale, locale } = inject('i18n')
4</script>
5
6<template>
7 <nav>
8 <a>{{ t('nav.home') }}</a>
9 <a>{{ t('nav.settings') }}</a>
10 </nav>
11 <p>Status: {{ t('status.online') }}</p>
12 <button @click="setLocale('en')">EN</button>
13 <button @click="setLocale('pl')">PL</button>
14</template>