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();
}
相关推荐
江城开朗的豌豆4 分钟前
Vue路由动态生成秘籍:让你的链接'活'起来!
前端·javascript·vue.js
江城开朗的豌豆10 分钟前
在写vue公用组件的时候,怎么提高可配置性
前端·javascript·vue.js
江城开朗的豌豆10 分钟前
Vue路由跳转的N种姿势,总有一种适合你!
前端·javascript·vue.js
江城开朗的豌豆11 分钟前
Vue路由玩法大揭秘:三种路由模式你Pick谁?
前端·javascript·vue.js
江城开朗的豌豆12 分钟前
Vue路由守卫全攻略:给页面访问装上'安检门'
前端·javascript·vue.js
江城开朗的豌豆24 分钟前
Vue路由传参避坑指南:params和query的那些猫腻
前端·javascript·vue.js
十里青山32 分钟前
超好用的vue图片预览插件更新啦,hevue-img-preview 7.0.0版本正式发布,支持vue2/vue3/移动/pc,增加缩略图、下载、自定义样式等
前端·javascript·vue.js
daols887 小时前
vue vxe-table 自适应列宽,根据内容自适应宽度的2种使用方式
vue.js·vxe-table
行云&流水10 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
三水气象台10 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue