Loading... # Vuetify, Pinia 实现一个简单的通知 ## 前言 以前用element-ui的时候有非常方便的`$notify`方法来使用通知,Vuetify暂时没有类似功能,但是有相同作用的组件[消息条Snackbars](https://vuetifyjs.com/zh-Hans/components/snackbars/)。 所以我们可以使用pinia和消息条来实现一个类似的功能,不多废话,直接上代码 ## 代码 ### Store `useToastStore.ts` ```ts import type { ToastState } from '~/types/stores/toast-type' interface ToastState { /** 通知内容 */ msg: string; /** 通知颜色 */ color: string; /** 显示 */ visible?: boolean; /** 是否显示关闭按钮 */ showClose?:boolean; /** 超时时间 */ timeout?: number; /** 防抖计时器 */ debounceTimer?: NodeJS.Timeout | null } export const useToastStore = defineStore('toastStore', { state: ():ToastState => { return { msg: '', color: 'info', visible: false, showClose: true, timeout: 5000, debounceTimer: null } }, actions: { /** * 显示通知 * @param options 参数 */ open (options:ToastState) { this.msg = options.msg if (options?.color) { this.color = options.color } if (options?.timeout) { this.timeout = options.timeout } this.visible = true // 防抖 if (this.debounceTimer) { clearTimeout(this.debounceTimer) } this.debounceTimer = setTimeout(() => { this.visible = false }, this.timeout) }, /** * 成功通知 * @param msg 消息 */ success (msg:string) { this.open({ msg, color: 'success' }) }, /** * 错误通知 * @param msg 消息 */ error (msg:string) { this.open({ msg, color: 'error' }) }, /** * info通知 * @param msg 消息 */ info (msg:string) { this.open({ msg, color: 'info' }) }, /** * 警告通知 * @param msg 消息 */ warning (msg:string) { this.open({ msg, color: 'warning' }) } } }) ``` ### 消息条组件 `GlobalMessageBar.vue` 样式自己随便改,注意下这边的`timeout`写的是`-1`,来手动控制通知的显示 ```vue <script setup lang="ts"> import { useToastStore } from '~/stores/toast-store' const toast = useToastStore() </script> <template> <v-snackbar v-model="toast.visible" :color="toast.color" timeout="-1" rounded="pill" min-width="300" > {{ toast.msg }} <template #actions> <v-btn color="white" icon="mdi-close" @click="toast.visible = false" /> </template> </v-snackbar> </template> <style scoped> </style> ``` ## 使用 > 注意:`v-snackbar`必须放在`v-app`下使用 我这边直接放在布局文件里面了 ```vue <script setup lang="ts"> </script> <template> <v-app> <div> <slot /> </div> <GlobalMessageBar /> </v-app> </template> <style scoped> </style> ``` ```vue <script setup lang="ts"> const toastStore = useToastStore() const testToast = () => { toastStore.success('测试通知') } </script> <template> <nuxt-layout name="default"> <v-btn @click="testToast" > 测试通知 </v-btn> </nuxt-layout> </template> <style scoped> </style> ``` ![image-20240117020825249](https://i.imgur.com/jG4zMLb.png) 最后修改:2024 年 01 月 17 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏