- 一个模版文件Toast.vue
- 一个渲染挂载导出方法文件index.ts
- 通过Toast.success(‘xxxx’) 调用
这里UI使用Flowbite
的Toast组件(需要配合tailwindcss)
供给渲染的模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| <script lang="ts" setup> import { ref } from 'vue' interface Props { visible: boolean type: string message: string } const props = withDefaults(defineProps<Props>(), { visible: false, type: '', message: '' })
const status = props.type === 'success' ? 'success' : 'danger' const toast = ref<HTMLDivElement>() const handleClose = () => { toast.value!.style.display = 'none' } </script>
<template> <Transition name="toast" enter-active-class="transition ease-out duration-300" leave-active-class="transition ease-in duration-300" > <div class="fixed inset-0 h-0" v-if="props.visible"> <div :id="`toast-${status}`" class="absolute top-5 left-1/2 -translate-x-1/2 flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800" role="alert" ref="toast" > <div v-if="props.type === 'success'" class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200" > <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20" > <path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z" /> </svg> <span class="sr-only"> Check icon </span> </div>
<div v-else-if="props.type === 'error'" class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-red-500 bg-red-100 rounded-lg dark:bg-red-800 dark:text-red-200" > <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20" > <path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 11.793a1 1 0 1 1-1.414 1.414L10 11.414l-2.293 2.293a1 1 0 0 1-1.414-1.414L8.586 10 6.293 7.707a1 1 0 0 1 1.414-1.414L10 8.586l2.293-2.293a1 1 0 0 1 1.414 1.414L11.414 10l2.293 2.293Z" /> </svg> <span class="sr-only"> Error icon </span> </div> <div class="ml-3 text-sm font-normal"> <!-- {/* 不同 */} --> {{ props.message }} </div> <button type="button" class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex items-center justify-center h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700" data-dismiss-target="#toast-success" aria-label="Close" @click="handleClose" > <span class="sr-only">Close</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14" > <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" /> </svg> </button> </div> </div> </Transition> </template>
<style scoped> .toast-enter-from, .toast-leave-to { opacity: 0; transform: translateY(-30px); } </style>
|
导出toast方法,提供给Vue进行挂载
index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| import { createApp, h } from 'vue' import ToastComponent from './template/Toast.vue'
interface ToastProps { visible: boolean type: 'success' | 'error' message: string }
const ToastContainer = createApp({ render() { return h(ToastComponent, this.toastProps) }, data() { return { toastProps: { visible: false, type: '', message: '' } as unknown as ToastProps } } })
const toast = ToastContainer.mount(document.createElement('div'))
document.body.appendChild(toast.$el)
const Toast = { success(message: string) { toast.toastProps = { visible: true, type: 'success', message } setTimeout(() => { toast.toastProps.visible = false }, 3000) }, error(message: string) { toast.toastProps = { visible: true, type: 'error', message } setTimeout(() => { toast.toastProps.visible = false }, 3000) } }
export default Toast
|
👨💻使用
1 2
| Toast.success('hello') Toast.error('world')
|