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();
}
相关推荐
岁月宁静1 小时前
RAG 文档摄入全链路,从原理到生产落地
vue.js·人工智能·python
#麻辣小龙虾#3 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
一 乐4 小时前
家政服务管理系统|基于springboot + vue家政服务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·家政服务管理系统
独泪了无痕7 小时前
Vue3中防御XSS攻击的“特效药”-DOMPurify
前端·vue.js·安全
云水一下8 小时前
Vue.js从零到精通系列(五):全局状态管理——Pinia 核心与实践
前端·javascript·vue.js
老马聊技术8 小时前
AI对话功能之SpringBoot整合Vue3
vue.js·人工智能·spring boot·后端
英勇无比的消炎药9 小时前
一站式汇总TinyVue工具案例与真实落地经验
vue.js·前端框架
梵得儿SHI11 小时前
Vue 项目实战与性能优化全攻略:从代码、渲染到首屏,一站式解决卡顿慢加载
前端·vue.js·性能优化·vite·前端面试·前端优化·首屏优化
一 乐13 小时前
幼儿园管理系统|基于springboot + vue幼儿园管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·幼儿园管理系统
云水一下13 小时前
Vue.js从零到精通系列(七):高级特性实战——Teleport、异步组件、自定义指令与TypeScript深度结合
前端·vue.js·typescript