vue3 消息闪现


始终只显示一个

Notification.vue:

html
<template>
    <div v-if="show" aria-live="assertive" class="pointer-events-none fixed inset-0 flex px-4 py-6 items-start sm:p-6 z-10">
      <div class="flex w-full flex-col items-center sm:items-end space-y-2">
        <div class="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
          <div class="p-4">
            <div class="flex items-start">
              <div class="flex-shrink-0">
                <svg v-if="props.notification.type === 'err'" viewBox="0 0 20 20" fill="currentColor" class="h-6 w-6 text-yellow-500">
                  <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
                </svg>
                <svg v-else class="h-6 w-6 text-green-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <div class="ml-3 w-0 flex-1 pt-0.5">
                <p class="text-sm font-medium text-gray-900">{{ props.notification.msg }}</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { watch,ref } from 'vue';
  
  // 通过 props 接收通知参数
  const props = defineProps({
    notification: Object,
  });
  const show = ref(false);
  
    watch(props, () => {
        show.value = true; // 显示通知
        // 3 秒后关闭通知
        setTimeout(() => {
            show.value = false;
        }, 3000); // 通知显示 3 秒后自动隐藏
    });
  </script>

调用方法:

html
<template>
  <Notification :notification="notification" />
</template>

<script setup>
  import { ref} from 'vue';
	import Notification from './Notification.vue'; // 引入通知组件
	 const notification = ref({}); //通知
	
	// 假设下面是某函数中
	notification.value = {msg: '复制成功',type:"success"};
</script>

数组方法(推荐)

html
<template>
    <div aria-live="assertive" class="pointer-events-none fixed inset-0 flex px-4 py-6 items-start sm:p-6 z-10">
        <div class="flex w-full flex-col items-center sm:items-end space-y-2">
            <div v-for="(notification) in notifications" class="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
                <div class="p-4">
                    <div class="flex items-start">
                        <div class="flex-shrink-0">
                            <svg v-if="notification.type === 'err'" viewBox="0 0 20 20" fill="currentColor"
                                class="h-6 w-6 text-yellow-500">
                                <path fill-rule="evenodd"
                                    d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
                                    clip-rule="evenodd" />
                            </svg>
                            <svg v-else class="h-6 w-6 text-green-400" fill="none"
                                viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                            </svg>
                        </div>
                        <div class="ml-3 w-0 flex-1 pt-0.5">
                            <p class="text-sm font-medium text-gray-900"> {{ notification.msg }}</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
  </template>
<script setup>
import { watchEffect } from 'vue';

const props = defineProps({
    notifications: Array,
});

watchEffect(() => {
    props.notifications.forEach((_, index) => {
        // 在定时器结束后从数组中移除该通知对象
        setTimeout(() => {
            props.notifications.splice(index, 1);
        }, 3000);
    });
});
</script>

在其他方法中调用

html
<template>
  <Notification :notification="notification" />
</template>

<script setup>
	import { ref} from 'vue';
	import Notification from './Notification.vue'; // 引入通知组件
	const notifications = ref([]); //通知
	
	// 假设下面是某函数中
	notifications.value.push({msg: '复制成功',type:"success"});
</script>