lunes, 25 de julio de 2022

📦 Componente Toast en Vue

El componente Toast es un elemento UI que permite dar una retroalimentación de lo que está pasando en segundo o primer plano de alguna acción que ha hecho el usuario en tu aplicación.

Lógica (Domain)

Toast

import { ToastBody } from "./ToastBody";import { ToastPosition } from "./ToastPositions";export class Toast {  id: number  position: ToastPosition;  body: ToastBody;  duration: number;  constructor(body: ToastBody, position: ToastPosition, duration?: number) {    this.id = this.randomId()    this.body = body;    this.position = position;    this.duration = duration ?? 2500;  }  private randomId() {    return Math.floor(Math.random() * new Date().getMilliseconds());  }}

ToastBody

type ToastProps = {  title: string;  color?: string;  icon?: any;  description: string;};export class ToastBody {  title: string;  description: string;  icon: any;  color: string = "";    constructor(props: ToastProps) {    this.title = props.title;    this.description = props.description;    this.color = props.color ?? "green";    this.icon = props.icon ?? "";  }}

ToastPosition

export type ToastPosition = "top" | "bottom";

Casos de uso (Aplications)

useToast

import { Toast } from "../domain/Toast";import { ToastBody } from "../domain/ToastBody";import { ToastsOnReactiveMemory } from "../infraestructure/persistence";const toastOnReactiveMemory = new ToastsOnReactiveMemory();export function useToast() {  const add = ( title: string, description: string, color?: string, icon?: string ) => {    const toast = new Toast(      new ToastBody({        title,        description,        color,        icon,      }),      "top"    );    toastOnReactiveMemory.add(toast);  };  const remove = (toast: Toast) => {    toastOnReactiveMemory.remove(toast);  };  return {    toasts: toastOnReactiveMemory.toasts,    add,    remove,  };}

Persistencia (Infraestructure)

Persistencia en memoria reactiva

import { ref, Ref } from "vue";import { Toast } from "../domain/Toast";export class ToastsOnReactiveMemory {  private conatiner: Ref<Toast[]> = ref([]);  add(toast: Toast) {    this.toasts.value.push(toast);  }  remove(toast: Toast) {    const index = this.toasts.value.findIndex((t) => t.id === toast.id);    this.toasts.value.splice(index, 1);  }  get toasts() {    return this.conatiner;  }}

Componentes

Los estilos quedan a tu imaginación

ToastContainer

La función principal de este componente es recorrer el contenedor de los toast y asignar sus propiedades.

<template>  <div>    <span v-for="t of toasts">      <Toast :toast="t" />    </span>  </div></template><script lang="ts" setup>import { useToast } from './application/useToast'import Toast from './Toast.vue'const { toasts } = useToast()</script>

Toast

La responsabilidad de este componente es solo obtener los atributos desde el ToastContainer y mostrarlos

<template>  {{ toast.id }}  {{ toast.body }}</template><script lang="ts" setup>import { onMounted } from 'vue';import { useToast } from './application/useToast';import { Toast } from './domain/Toast';const props = defineProps<{  toast: Toast}>()const { remove } = useToast()onMounted(() => {  const time = setTimeout(() => {    remove(props.toast)    clearTimeout(time)  }, props.toast.duration)})</script>
Desarrollado con Nuxt 3 💚
Erik Ciau Apple Emoji To Love