uniapp踩坑 uni.showToast 和 uni.showLoading

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();
}
相关推荐
customer083 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
getaxiosluo1 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js
前端啊龙2 小时前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js
断墨先生2 小时前
uniapp—android原生插件开发(3Android真机调试)
android·uni-app
小远yyds3 小时前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
程序媛小果3 小时前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
小光学长3 小时前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
guai_guai_guai4 小时前
uniapp
前端·javascript·vue.js·uni-app