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();
}
相关推荐
@yanyu6666 小时前
登录注册功能-明文
vue.js·springboot
滕青山10 小时前
在线PDF拆分工具核心JS实现
前端·javascript·vue.js
专科3年的修炼15 小时前
uni-app移动应用开发第四章
开发语言·javascript·uni-app
光影少年17 小时前
前端在页面渲染优化和组件优化经验?
前端·vue.js·react.js·前端框架
q55070717718 小时前
uniapp/uniappx实现原生图片编辑涂鸦、贴图、滤镜、旋转、裁剪等
uni-app
李白的天不白19 小时前
VUE依赖配置问题
前端·javascript·vue.js
小智社群20 小时前
获取贝壳新房列表
前端·javascript·vue.js
一 乐20 小时前
茶叶商城|基于springboot + vue茶叶商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·茶叶商城系统
吴声子夜歌21 小时前
Vue3——Pinia状态管理
javascript·vue.js·pinia
追风筝的人er1 天前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端