uniapp踩坑 uni.showToast 和 uni.showLoading
一、问题描述
- uni.showLoading 和 uni.showToast 混合使用时,showLoading和showToast会相互覆盖对方,调用hideLoading时也会将toast内容进行隐藏。
二、触发条件
- 1.uniapp中使用自己封装的axois,拦截器使用 uni.showToast 做异常信息处理
- 2.业务中使用 uni.showLoading 做业务处理
- 3.当请求异常被catch抓到,使用 uni.hideLoading 清除 loading 时,异常信息 toast 会被覆盖掉。
三、解决思路
- 小程序将Toast和Loading放到同一层渲染引起的,而且缺乏一个优先级判断,也没有提供Toast、Loading是否正在显示的接口供业务侧判断。所以我们自己实现这套逻辑,判断其中有一个已经渲染,泽不执行另一个。
四、实现方案
1.封装一下toast和loading
js
复制代码
/**
* 显示消息提示框
* @param title
* @param options
* @constructor
*/
export function Toast(title: string, options?: Partial<UniApp.ShowToastOptions>) {
uni.showToast({
title,
duration: 1500,
icon: 'none',
mask: true,
...options,
});
}
/**
* 隐藏消息提示框
*/
export function HideToast() {
uni.hideToast();
}
/**
* 显示 loading 提示框
* @param title
* @param options
* @constructor
*/
export function Loading(title: string, options?: Partial<UniApp.ShowLoadingOptions>) {
uni.showLoading({
title,
mask: true,
...options,
});
}
/**
* 隐藏 loading 提示框
*/
export function HideLoading() {
uni.hideLoading();
}
2.要加个变量控制toast和loading的优先级,最简单就是通过vue的全局状态管理来控制
js
复制代码
export const usePromptStore = defineStore({
id: 'promptStore',
state: (): IState => ({
isShowLoading: false,
isShowToast: false,
}),
getters: {
getIsShowLoading: (state) => state.isShowLoading,
getIsShowToast: (state) => state.isShowToast,
},
actions: {
setIsShowLoading(val: boolean) {
this.isShowLoading = val;
},
setIsShowToast(val: boolean) {
this.isShowToast = val;
},
},
});
3.改造一下封装的toast和loading
js
复制代码
/**
* 显示消息提示框
* @param title
* @param options
* @constructor
*/
export function Toast(title: string, options?: Partial<UniApp.ShowToastOptions>) {
const promptStore = usePromptStore();
if (promptStore.disabledToast) return;
if (promptStore.isShowLoading) {
// Toast优先级更高
HideLoading();
}
promptStore.setIsShowToast(true);
uni.showToast({
title,
duration: 1500,
icon: 'none',
mask: true,
...options,
});
const timer = setTimeout(() => {
promptStore.setIsShowToast(false);
clearTimeout(timer)
}, 1500);
}
/**
* 隐藏消息提示框
*/
export function HideToast() {
const promptStore = usePromptStore();
promptStore.setIsShowToast(false);
uni.hideToast();
}
/**
* 显示 loading 提示框
* @param title
* @param options
* @constructor
*/
export function Loading(title: string, options?: Partial<UniApp.ShowLoadingOptions>) {
const promptStore = usePromptStore();
if (promptStore.isShowToast) {
// Toast优先级更高
return;
}
promptStore.setIsShowLoading(true);
uni.showLoading({
title,
mask: true,
...options,
});
}
/**
* 隐藏 loading 提示框
*/
export function HideLoading() {
const promptStore = usePromptStore();
if (promptStore.isShowToast) {
// Toast优先级更高
return;
}
promptStore.setIsShowLoading(false);
uni.hideLoading();
}