un1t
@un1t

Vue как отобразить сообщения ровно один раз?

Хочу показывать сообщения о том что операция завершилась успешно или с ошибкой.
Из любого компонента можно вызвать некую функцию например addMessage и оно должно отобразиться на экране сразу или после редиректа (например при создании нового объекта).

Решил, что для хранения таких сообщений подойдет стейт менеджер (у меня pinia), а для отображения отдельный компонент. С добавлением и отображением нет никаких проблем, но не понятно как эти сообщения удалить сразу после отображения из store, но при этом, чтобы они оставлись на экране.

store.ts
import { defineStore } from 'pinia'

export enum Level {
    Success,
    Warning,
    Error,
}

export type Message = {
    level: Level;
    text: string;
}

export const useMessagesStore = defineStore('messages', {
    state: () => {
        return {
            messages: [] as Array<Message>,
        }
    },
    actions: {
        addMessage(level: Level, text: string) {
            this.messages.push({ level: level, text: text })
        },
        popMessages() {
            const result = this.messages.slice().reverse()
            this.messages = []
            return result
        },
    },
})


Messages.vue
<template>
  <div>
    <article
      class="message"
      :class="{
        'is-success': message.level == Level.Success,
        'is-danger': message.level == Level.Error,
        'is-warning': message.level == Level.Warning,
      }"
      v-for="message in messagesReversed"
      :key="message.level + message.text"
    >
      <div class="message-body">
        {{ message.text }}
      </div>
    </article>
  </div>
</template>


<script lang="ts">
import { defineComponent } from "vue";
import { Level, useMessagesStore } from "@/stores/messages";
import { storeToRefs } from "pinia";

export default defineComponent({
  data() {
    let messagesStore = useMessagesStore();
    const { messages } = storeToRefs(messagesStore);
    return {
      messages: messages,
      Level: Level,
    };
  },
  computed: {
    messagesReversed() {
      return useMessagesStore().popMessages()
    },
  },
});
</script>
  • Вопрос задан
  • 72 просмотра
Решения вопроса 1
Aetae
@Aetae Куратор тега Vue.js
Тлен
Очевидный ответ - не удалять из store пока они остаются на экране.)
Если юзер может их "закрыть" - удалять по событию закрытия.
Если они должны пропадать по таймауту - удалять по таймауту.
Иначе - удалять по хуку onUnmounted компонента.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы