uniapp提示成功之后再跳转页面
oopsoh
一个面向 uni-app 的轻量交互工具库,用来优雅处理页面里常见的提示、跳转、确认弹窗、加载态和防重复提交。
GitHub: https://github.com/im76ix/oopsoh
Gitee: https://gitee.com/im76ix/oopsoh
为什么需要 oopsoh
相信经常使用 uni-app 的同学都遇到过这个问题:提交表单成功后,想先给用户一个成功提示,再跳转到下一个页面。
但如果直接这样写:
uni.showToast({
title: "保存成功",
duration: 1500,
})
uni.navigateTo({
url: "/pages/list/index",
})
页面会立刻跳走,提示几乎一闪而过。因为 uni.showToast 是异步展示的,它不会阻塞后面的跳转逻辑。
通常我们会手动加 setTimeout:
uni.showToast({
title: "保存成功",
duration: 1500,
})
setTimeout(() => {
uni.navigateTo({
url: "/pages/list/index",
})
}, 1500)
可以用,但不够优雅,也很容易在项目里重复出现。
oopsoh 就是为了解决这些页面交互小流程而生。
安装
npm i oopsoh
或:
pnpm add oopsoh
导入方式
oopsoh 同时支持命名空间写法和函数式写法。
推荐写法
import oh from "oopsoh"
oh.success("保存成功")
oh.to("保存成功", "/pages/list/index")
函数式写法
import { toast, confirm, withLoading } from "oopsoh"
toast("hello world")
await confirm("确定删除吗?")
await withLoading("提交中", submit)
兼容旧写法
旧版本的 oh(msg, options, callback) 仍然可以继续使用。
import { oh } from "oopsoh"
oh("保存成功", { ico: "success" }, () => {
uni.navigateTo({
url: "/pages/list/index",
})
})
快速开始
简单提示
oh.toast("hello world")
也可以直接调用 oh,效果等同于 oh.toast:
oh("hello world")
函数式写法:
import { toast } from "oopsoh"
toast("hello world")
成功提示
oh.success("保存成功")
等同于:
oh.toast("保存成功", { icon: "success" })
失败提示
oh.error("提交失败")
加载提示
这是基于 uni.showToast 的 loading 图标提示,适合短时间反馈。
oh.loading("加载中")
如果是异步任务的全局加载态,建议使用 oh.withLoading。
提示后跳转
navigateTo
跳转到非 tabBar 页面。
oh.to("/pages/detail/index")
提示完成后再跳转:
oh.to("保存成功", "/pages/list/index", {
icon: "success",
duration: 1500,
})
传递 uni.navigateTo 原生参数:
oh.to("保存成功", "/pages/list/index", {
icon: "success",
route: {
animationType: "pop-in",
animationDuration: 300,
},
})
redirectTo
关闭当前页面并跳转。
oh.redirect("/pages/result/index")
提示完成后再跳转:
oh.redirect("提交成功", "/pages/result/index", {
icon: "success",
})
reLaunch
关闭所有页面并打开某个页面,常用于登录过期、切换身份、回到首页等场景。
oh.reLaunch("登录已过期", "/pages/login/index", {
icon: "none",
})
switchTab
跳转到 tabBar 页面。
oh.tab("/pages/home/index")
提示完成后跳转到 tabBar 页面:
oh.tab("发布成功", "/pages/home/index", {
icon: "success",
})
navigateBack
直接返回上一页:
oh.back()
返回指定层级:
oh.back(2)
提示完成后再返回:
oh.back("保存成功", {
icon: "success",
delta: 1,
})
确认弹窗
oh.confirm 基于 uni.showModal 封装,用户点击确认时执行回调并返回 true,取消时返回 false。
const ok = await oh.confirm("确定删除这条数据吗?")
if (ok) {
await deleteItem()
}
也可以把确认后的逻辑直接交给它:
await oh.confirm("确定删除这条数据吗?", async () => {
await deleteItem()
oh.success("删除成功")
})
自定义按钮文案:
await oh.confirm(
"删除后不可恢复,确定继续吗?",
deleteItem,
{
title: "删除确认",
confirmText: "删除",
cancelText: "再想想",
confirmColor: "#e54d42",
},
)
函数式写法:
import { confirm } from "oopsoh"
await confirm("确定退出登录吗?", logout)
加载态包裹异步任务
oh.withLoading 会自动调用 uni.showLoading 和 uni.hideLoading。不论任务成功还是失败,都会在结束时关闭 loading。
await oh.withLoading("提交中", async () => {
await submitForm()
})
获取任务返回值:
const user = await oh.withLoading("加载用户信息", async () => {
return await getUserInfo()
})
关闭透明蒙层:
await oh.withLoading(
"加载中",
loadData,
{
mask: false,
},
)
函数式写法:
import { withLoading } from "oopsoh"
await withLoading("保存中", saveData)
防重复提交
oh.lock 可以给函数加运行锁,防止按钮连点造成重复提交。
const submitOnce = oh.lock(async () => {
await submitForm()
oh.success("提交成功")
})
submitOnce()
重复触发时给用户提示:
const submitOnce = oh.lock(submitForm, {
message: "正在提交,请稍候",
})
任务结束后延迟解锁:
const payOnce = oh.lock(createPayOrder, {
message: "支付处理中",
delay: 1000,
})
在 Vue 页面中使用:
<script setup lang="ts">
import oh from "oopsoh"
const submit = oh.lock(async () => {
await oh.withLoading("提交中", async () => {
// await api.submit(...)
})
oh.to("提交成功", "/pages/list/index", {
icon: "success",
})
})
</script>
<template>
<button @click="submit">提交</button>
</template>
API 总览
oh / toast
oh(msg: string, options?: ToastOptions, callback?: () => void): void
oh.toast(msg: string, options?: ToastOptions, callback?: () => void): void
toast(msg: string, options?: ToastOptions, callback?: () => void): void
显示普通提示。callback 会在提示展示时长结束后执行。
success
oh.success(msg: string, options?: ToastOptions, callback?: () => void): void
显示成功提示,默认 icon 为 success。
error
oh.error(msg: string, options?: ToastOptions, callback?: () => void): void
显示失败提示,默认 icon 为 error。
loading
oh.loading(msg?: string, options?: ToastOptions, callback?: () => void): void
显示 loading 类型的 Toast,默认文案为 加载中。
confirm
oh.confirm(
content: string,
onConfirm?: () => void | Promise<void>,
options?: ConfirmOptions,
): Promise<boolean>
显示确认弹窗。确认返回 true,取消返回 false。
to
oh.to(url: string, options?: NavigateOptions): void
oh.to(msg: string, url: string, options?: ToastRouteOptions): void
跳转到非 tabBar 页面,对应 uni.navigateTo。
redirect
oh.redirect(url: string, options?: RedirectOptions): void
oh.redirect(msg: string, url: string, options?: ToastRouteOptions): void
关闭当前页面并跳转,对应 uni.redirectTo。
reLaunch
oh.reLaunch(url: string, options?: ReLaunchOptions): void
oh.reLaunch(msg: string, url: string, options?: ToastRouteOptions): void
关闭所有页面并跳转,对应 uni.reLaunch。
tab
oh.tab(url: string, options?: SwitchTabOptions): void
oh.tab(msg: string, url: string, options?: ToastRouteOptions): void
跳转到 tabBar 页面,对应 uni.switchTab。
back
oh.back(delta?: number): void
oh.back(msg: string, options?: BackOptions): void
返回上一页或指定层级,对应 uni.navigateBack。
withLoading
oh.withLoading<T>(
title: string,
task: () => T | Promise<T>,
options?: LoadingOptions,
): Promise<T>
用 uni.showLoading 包裹一个同步或异步任务,并自动关闭 loading。
lock
oh.lock<Args extends unknown[], Result>(
task: (...args: Args) => Result | Promise<Result>,
options?: LockOptions,
): (...args: Args) => Promise<Result | undefined>
给函数增加运行锁,防止重复点击、重复提交。
参数说明
ToastOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
icon |
"success" | "error" | "loading" | "none" |
"none" |
Toast 图标 |
ico |
"success" | "error" | "loading" | "none" |
- | 兼容旧版本字段,等同于 icon |
duration |
number |
1500 |
提示展示时长,单位 ms |
mask |
boolean |
false |
是否显示透明蒙层 |
image |
string |
- | 自定义图标图片路径 |
success |
UniApp.ShowToastOptions["success"] |
- | uni.showToast 原生成功回调 |
fail |
UniApp.ShowToastOptions["fail"] |
- | uni.showToast 原生失败回调 |
complete |
UniApp.ShowToastOptions["complete"] |
- | uni.showToast 原生完成回调 |
ToastRouteOptions
ToastRouteOptions 继承 ToastOptions,额外支持:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
route |
object |
- | 传给原生跳转 API 的参数,不包含 url |
示例:
oh.to("保存成功", "/pages/list/index", {
icon: "success",
route: {
animationType: "pop-in",
},
})
ConfirmOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title |
string |
"提示" |
弹窗标题 |
confirmText |
string |
"确定" |
确认按钮文案 |
cancelText |
string |
"取消" |
取消按钮文案 |
showCancel |
boolean |
true |
是否显示取消按钮 |
confirmColor |
string |
- | 确认按钮颜色 |
cancelColor |
string |
- | 取消按钮颜色 |
success |
UniApp.ShowModalOptions["success"] |
- | uni.showModal 原生成功回调 |
fail |
UniApp.ShowModalOptions["fail"] |
- | uni.showModal 原生失败回调 |
complete |
UniApp.ShowModalOptions["complete"] |
- | uni.showModal 原生完成回调 |
BackOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
delta |
number |
1 |
返回的页面层数 |
BackOptions 同时继承 ToastOptions,所以也可以传入 icon、duration、mask 等提示参数。
LoadingOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
mask |
boolean |
true |
是否显示透明蒙层 |
LockOptions
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
message |
string |
- | 重复触发时的提示文案 |
delay |
number |
0 |
任务结束后延迟多久解锁,单位 ms |
onLocked |
() => void |
- | 重复触发时的自定义处理 |
完整示例
import oh from "oopsoh"
const submit = oh.lock(async () => {
await oh.withLoading("提交中", async () => {
// await api.submitForm()
})
oh.to("提交成功", "/pages/list/index", {
icon: "success",
duration: 1500,
})
}, {
message: "正在提交,请勿重复点击",
})
TypeScript
oopsoh 自带类型声明,安装后即可获得类型提示。
import type {
ToastOptions,
ConfirmOptions,
ToastRouteOptions,
LockOptions,
} from "oopsoh"
旧版本的 OhOptions 类型仍然保留:
import type { OhOptions } from "oopsoh"
兼容说明
- 保留
oh("提示", options, callback)旧写法。 - 保留
ico字段,推荐新项目使用icon。 - 新增默认导出
oh,推荐import oh from "oopsoh"。 - 新增具名函数导出,支持按需导入。
建议与反馈
如果你在使用过程中有更好的想法,欢迎在 GitHub 或 Gitee 提 issue。
如果这个小库刚好帮你少写了一点重复代码,也欢迎点个 Star。
更多推荐


所有评论(0)