uni-app 无法实现全局 Toast?这个方法做到了!

news/2025/11/17 14:49:18/文章来源:https://www.cnblogs.com/smileZAZ/p/19232719

🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣

大家好,我是不如摸鱼去,wot-ui的主要维护者,欢迎来到我的 uni-app 分享专栏。

在 uni-app 开发中,我们经常遇到需要在任何地方(如网络请求拦截器、>路由守卫等)显示 Toast 提示的需求。然而,uni-app 的组件化架构使>得全局 Toast 的实现变得复杂。本文将介绍一套完整的解决方案,让你轻松>实现真正的全局 Toast。

本文实现的全局 Toast、Loading、MessageBox 等组件均已在现代化 uni-app 模板,基于vitesse-uni-app的深度整合 Wot UI 组件库的快速起手项目 wot-demo 中提供,模板地址在文章末尾,作者是其主要维护者。

问题分析

传统方案的局限性

在 uni-app 中,常见的 Toast 实现方式有以下几种:

  1. uni.showToast() - 功能有限,样式单一,无法自定义
  2. 传统Toast - 只能在当前组件使用,无法跨组件调用
  3. wot ui 方案 - 基于provide/inject实现,需要在 setup 顶层调用useToast,无法在路由拦截和请求拦截中使用

核心难点

  • uni-app 无法像 Vue 3 那样全局挂载组件
  • 组件实例无法在非 Vue 上下文中访问
  • 需要在网络请求和路由拦截中使用 Toast

解决方案架构

我们的解决方案包含三个核心部分:

  1. wd-toast 组件 - 基于 provide/inject 的函数式调用
  2. Layout 插件 - 实现一次插入,全局可用
  3. useGlobalToast - 基于 Pinia 的状态管理

实现详解

1. wd-toast 组件实现

wot ui 是一个当下流行的 uni-app vue3 UI 库,作者也是其重要维护者之一。

首先,我们使用 wot-ui 的 Toast 组件,它基于 provide/inject 实现函数式调用:

<!-- 在组件中使用 -->
<script setup>
const toast = useToast('myToast')// 显示 Toast
toast.show({msg: '这是一个提示',duration: 2000
})
</script><template><wd-toast selector="myToast" />
</template>

优点: 函数式调用,使用简单 缺点: useToast 必须在 setup 顶层调用,toast.show 仅能在vue组件中使用

2. Layout 插件 - 一次插入,全局可用

由于 uni-app 无法全局插入组件,我们通过 @uni-helper/vite-plugin-uni-layouts 插件实现统一布局管理:

<!-- src/layouts/default.vue -->
<template><wd-config-provider :theme-vars="themeVars" :theme="theme"><slot /><!-- 全局组件一次性插入 --><wd-notify /><wd-message-box /><wd-toast /><global-loading /><global-toast /><global-message /></wd-config-provider>
</template>

这样,所有页面都会包含这些全局组件,实现了"一次插入,全局可用"的效果。

3. GlobalToast 组件实现

<!-- src/components/GlobalToast.vue -->
<script lang="ts" setup>
const { toastOptions, currentPage } = storeToRefs(useGlobalToast())
const { close: closeGlobalToast } = useGlobalToast()const toast = useToast('globalToast')
const currentPath = getCurrentPath()// 支付宝小程序兼容性处理
// #ifdef MP-ALIPAY
const hackAlipayVisible = ref(false)
nextTick(() => {hackAlipayVisible.value = true
})
// #endif// 监听全局状态变化
watch(() => toastOptions.value, (newVal) => {if (newVal && newVal.show) {// 只在当前页面显示 Toastif (currentPage.value === currentPath) {toast.show(toastOptions.value)}}else {toast.close()}
})
</script><template><!-- 支付宝小程序特殊处理 --><!-- #ifdef MP-ALIPAY --><wd-toast v-if="hackAlipayVisible" selector="globalToast" :closed="closeGlobalToast" /><!-- #endif --><!-- #ifndef MP-ALIPAY --><wd-toast selector="globalToast" :closed="closeGlobalToast" /><!-- #endif -->
</template>

关键特性:

  • 通过 currentPage 确保 Toast 只在正确的页面显示
  • 支持支付宝小程序的兼容性处理
  • 使用 virtualHost 和 styleIsolation 优化结构和样式

4. useGlobalToast - Pinia 状态管理

// src/composables/useGlobalToast.ts
import { defineStore } from 'pinia'
import type { ToastOptions } from 'wot-design-uni/components/wd-toast/types'interface GlobalToast {toastOptions: ToastOptionscurrentPage: string
}const defaultOptions: ToastOptions = {duration: 2000,show: false,
}export const useGlobalToast = defineStore('global-toast', {state: (): GlobalToast => ({toastOptions: defaultOptions,currentPage: '',}),actions: {// 显示 Toastshow(option: ToastOptions | string) {this.currentPage = getCurrentPath()const options = CommonUtil.deepMerge(defaultOptions,typeof option === 'string' ? { msg: option } : option) as ToastOptionsthis.toastOptions = CommonUtil.deepMerge(options, {show: true,position: options.position || 'middle',}) as ToastOptions},// 成功提示success(option: ToastOptions | string) {this.show(CommonUtil.deepMerge({iconName: 'success',duration: 1500,}, typeof option === 'string' ? { msg: option } : option) as ToastOptions)},// 错误提示error(option: ToastOptions | string) {this.show(CommonUtil.deepMerge({iconName: 'error',direction: 'vertical',}, typeof option === 'string' ? { msg: option } : option) as ToastOptions)},// 信息提示info(option: ToastOptions | string) {this.show(CommonUtil.deepMerge({iconName: 'info',}, typeof option === 'string' ? { msg: option } : option) as ToastOptions)},// 警告提示warning(option: ToastOptions | string) {this.show(CommonUtil.deepMerge({iconName: 'warning',}, typeof option === 'string' ? { msg: option } : option) as ToastOptions)},// 关闭 Toastclose() {this.toastOptions = defaultOptionsthis.currentPage = ''},},
})

使用方式

1. 在组件中使用

<script setup>
const globalToast = useGlobalToast()function handleClick() {globalToast.success('操作成功!')globalToast.error('操作失败!')globalToast.info('提示信息')globalToast.warning('警告信息')
}
</script>

2. 在网络请求中使用

// 请求拦截器
uni.addInterceptor('request', {fail(err) {const globalToast = useGlobalToast()globalToast.error('网络请求失败')}
})// 或在 API 封装中
export async function apiRequest(url: string, data: any) {try {const result = await uni.request({ url, data })return result}catch (error) {const globalToast = useGlobalToast()globalToast.error('请求失败,请重试')throw error}
}

3. 在路由拦截中使用

// 路由守卫
function routeGuard(to: string) {const globalToast = useGlobalToast()if (!isLogin()) {globalToast.warning('请先登录')uni.navigateTo({ url: '/pages/login/index' })return false}return true
}

扩展功能

基于同样的架构,我们还实现了:

1. GlobalLoading - 全局加载提示

export const useGlobalLoading = defineStore('global-loading', {actions: {loading(option: ToastOptions | string) {this.currentPage = getCurrentPath()this.loadingOptions = CommonUtil.deepMerge({iconName: 'loading',duration: 0,cover: true,position: 'middle',show: true,}, typeof option === 'string' ? { msg: option } : option)}}
})

2. GlobalMessage - 全局弹窗

export const useGlobalMessage = defineStore('global-message', {actions: {alert(option: GlobalMessageOptions | string) {const messageOptions = CommonUtil.deepMerge({ type: 'alert' },CommonUtil.isString(option) ? { title: option } : option)messageOptions.showCancelButton = falsethis.show(messageOptions)}}
})

总结

通过这套方案,我们成功解决了 uni-app 全局 Toast 的难题:

  1. wd-toast 组件 提供了优秀的基础能力
  2. @uni-helper/vite-plugin-uni-layouts 插件 实现了统一布局和组件的全局插入
  3. Pinia 状态管理 让我们能在任何地方调用 Toast

这个方案具有以下优势:

  • 真正的全局调用,可在任何地方使用
  • 完整的类型支持
  • 多端兼容性
  • 页面隔离机制

如果你也在为 uni-app 的全局 Toast 而烦恼,不妨试试这个方案!

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/967952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

权重矩阵初始化

权重矩阵初始化 是神经网络训练中至关重要的一步,它直接影响模型的收敛速度和性能。不恰当的初始化可能导致梯度消失、梯度爆炸或训练停滞。 以下是常见的几种权重矩阵初始化方法: 零初始化 (Zero Initialization):…

2025较好的留学机构排名前十

2025较好的留学机构排名前十一、2025年留学中介选择:五大高频问题解析作为一名拥有15年经验的国际教育规划师,我经常接触到学生和家长的咨询,尤其是关于如何筛选可靠的留学中介。随着2025年留学季的临近,许多人在搜…

2025杭州最大留学中介公司在哪里

2025杭州最大留学中介公司在哪里一、杭州留学中介如何选?这些高频搜索问题你遇到过吗?作为一位在留学咨询行业耕耘超过十二年的国际教育规划师,我每天都会接触到大量来自杭州学生和家长的咨询。在2025年10月25日的今…

2025出国留学机构大全排名榜

2025出国留学机构大全排名榜一、2025出国留学机构大全排名榜作为拥有八年经验的国际教育规划师,我经常被学生和家长问到这样的问题:到底哪家留学中介更靠谱?选择机构时应该看重哪些方面?听说有些机构专门做研究生申…

2025成都有哪些留学中介机构比较好

2025成都有哪些留学中介机构比较好一、成都留学中介怎么选?这些高频问题帮你理清思路作为一位拥有12年经验的国际教育全案规划师,我经常被成都的学生和家长问及选择留学中介的种种困惑。在2025年的今天,成都的留学市…

使用 x11vnc 与 systemd 实现持久化 VNC 远程桌面服务

背景由于办公电脑系统重装,顺便就使用 Wireguard 异地组网的方案替代了原先的 ssh 隧道进行远程连接等一系列操作的方案。因此需要将服务端 x11vnc 作为一个持久服务,最好能通过 systemd 自动管理。方案先测试网络连…

上海外贸独立站公司十大推荐排行榜,谷歌独立站制作公司,谷歌独立站制作公司推荐,谷歌SEO公司排名前十,上海谷歌SEO公司十大排名:华企博网推荐榜

上海外贸独立站公司十大推荐排行榜,谷歌独立站制作公司,谷歌独立站制作公司推荐,谷歌SEO公司排名前十,上海谷歌SEO公司十大排名:华企博网推荐榜上海外贸独立站公司十大推荐排行榜,谷歌独立站制作公司,谷歌独立站…

2025 最新珩磨管厂家推荐!珩磨管 / 活塞杆 / 合金管 / 精密无缝管优质品牌排行榜,含 20#45#/304 材质数控珩磨工艺企业权威推荐

作为液压系统与传动部件的核心基础材料,珩磨管的精度、耐磨性与稳定性直接决定终端设备的运行效率与使用寿命。据国际流体动力协会(IFPS)最新测评数据显示,全球范围内仅 32% 的珩磨管企业能达到 Ra0.4 微米以下内壁…

2025上海外贸快车公司十大排名,上海外贸独立站制作公司排行,谷歌SEO公司十大排名,独立站源头公司口碑推荐榜,谷歌独立站公司推荐榜:华企博网评选十大优质服务商

2025上海外贸快车公司十大排名,上海外贸独立站制作公司排行,谷歌SEO公司十大排名,独立站源头公司口碑推荐榜,谷歌独立站公司推荐榜:华企博网评选十大优质服务商2025上海外贸快车公司十大排名,上海外贸独立站制作…

2025年口碑炸裂的湿敷水有哪些?抗初老+匀净透亮,成分党认准这几款

2025年口碑炸裂的湿敷水有哪些?抗初老+匀净透亮,成分党认准这几款随着美妆护肤理念的精细化发展,湿敷水作为高效护肤的核心单品,其市场需求呈现爆发式增长态势。专业的湿敷水通过密集补水、定向修护的特性,不仅能…

4、进程信号

1、信号 是软件中断,用于通知进程发生了某种事件。每个信号都有一个名字,以 SIG 开头。// 查看所有信号 kill -l// 输出示例:1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGAB…

说说Redis的集群方案?主从复制、哨兵、Cluster集群的区别和适用场景【转】

在现代分布式系统中,Redis 作为高性能的内存数据存储,其集群方案的选型直接决定了系统的稳定性、可用性和扩展性。本文将深入剖析 Redis 的三种核心集群方案:主从复制、哨兵模式和 Cluster 集群,结合实际应用案例厘…

2025年消波块钢模厂家推荐榜单Top10:行业权威解析与选择指南

摘要 随着海洋工程和港口建设的快速发展,消波块钢模作为防波堤核心组件,市场需求持续增长。2025年,行业预计增长率达8.5%,主要受益于沿海基础设施投资增加和环保政策推动。本文基于权威数据、用户口碑和技术指标,…

目前口碑好的消波块生产厂家推荐

文章摘要 本文推荐2025年口碑优秀的消波块生产厂家,重点介绍宁波添元水泥制品有限公司。作为行业领先者,添元水泥拥有30余年经验、先进设备和广泛案例,涵盖扭王字块、扭工字块等产品,服务全国沿海及内地工程,以专…

2025年国内消波块钢模厂家综合实力排行榜:添元水泥领跑行业

文章摘要 本文深入分析2025年国内消波块钢模厂家的技术实力、生产规模和服务能力,重点介绍宁波添元水泥制品有限公司作为行业领军企业的核心优势。通过对生产工艺、产品特点、技术创新和成功案例的全面解读,为港口工…

2025年污水管网检测公司权威推荐榜单:污水管网闭水检测/管网疏通检测/管网改造修复源头公司精选

随着城市基础设施老化问题日益凸显,中国污水管网检测市场规模预计在2025年将突破80亿元,其中专业的闭水检测与管网修复服务市场需求年增长率达18%,技术创新成为行业竞争核心 在城市化进程不断推进和环保要求日益严格…

2025年欧式门窗定制厂家权威推荐:别墅平开窗/手摇平开窗/智能窗源头厂家精选

欧式门窗系统以其典雅的设计、精湛的工艺和卓越的性能,在高端住宅、商业空间及别墅建筑中占据重要地位。随着建筑节能标准的提升和消费者审美的升级,市场对高性能定制门窗的需求持续增长。行业数据显示,2024年中国系…

热门十大跨境电商ERP盘点!做跨境电商的必备工具!

随着全球跨境电商市场规模持续扩大,2025年预计将突破8万亿美元,越来越多的卖家意识到手动处理订单、Excel管理库存的方式已无法满足业务需求。 面对多平台运营、海外仓储管理、跨境税务合规等复杂挑战,一款合适的ER…

Redis安装指导

Redis安装指导单机安装 一、前提条件获取redis软件包。获取方式请参考获取外部组件安装包。 检查redis默认端口6379是否被占用。如果被占用,http_port 需要更换其他端口,如16379 lsof -i:6379 有返回代表端口占用二、…

amd linux驱动

您提到的“AMD Linux驱动”可能是指用于AMD(Advanced Micro Devices)芯片组的Linux驱动程序,通常涉及GPU(图形处理单元)的驱动支持。以下是一些常见的AMD GPU驱动相关的Linux命令和脚本,适用于大多数Linux发行版…