uni-app项目loading显示方案

前情

uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE可视化的运行和打包也让开发体验也非常棒,公司项目就是主推uni-app,为了用户体验对于耗时操作,如接口请求或者异步的API调用都会添加loading效果

原生API使用持性

uni-app项目本身自带有原生交互反馈的API,如showToast、showLoading、showModal、showActionSheet,各有应用场景,而其中showLoading就是用于显示一个加载中效果的,同时跟他配套的还有hideLoading,用于隐藏已经显示的loading效果

showLoading特性:永远只会有一个,如果同时调用多次只会显示最后调用的那一个

hideLoading特性:调用它会关掉页面上的正在显示的loading

思考:

  • 因特性引起的一些使用问题

假设一个场景,我页面上同时调起二个接口,一个接口都会调起一个loading ,最后显示的是后调接口的loading,但是此时前一个接口回来了,会调用hideLoading接口,就会隐藏loading,其实第二个接口还没有回来,导致loading被关了,测试代码如下:

const test0 = () => {uni.showLoading({title: '加载中...0',mask: true});setTimeout(() => {uni.hideLoading();}, 1000);
}const test1 = () => {uni.showLoading({title: '加载中...1',mask: true});setTimeout(() => {uni.hideLoading();}, 2000);
}
test0();
test1();
  • 使用体验问题

在我们做接口请求的时候,接口速度是会受用户的网速影响,网速好就接口返回快,网络差就接口返回慢,这里会有一个问题,如果用户网络好那loading会闪一下就没了,用户都没看到是什么东西,在一定层面上给用户带来不好的体验

解决方案

  • 解决因特性引起的使用问题

因hideLoading并不会识别当前显示是由谁唤起的loading,导致无法识别当前要隐藏的是哪一个Loading,那我们就封装下代码,记录已经唤起的loading,在调用loading的时候通过传参指定要隐藏的是哪一个 loading就行了

  • 优化体验问题

我们无法确认用户的网络状态,那我们在唤起loading的时候是否可以做一个延时显示,假设我们延时为300ms,如果发现300ms内有唤起当前loading的hideloading调用,那当前loading也就不用显示了,但是这又有一个问题,如果网络正好回复时间了310,那一样是闪一下,所以我们再加一个loading的最小显示时间

uni-app项目一想到要全局操作,首选第一想到就是事件通信了,此处我们基于uni-app自带的事件通信 o n 、 on、 onemit来实现一个能解决上面缺陷的loading显示与隐藏方案,完整代码如下:

//  用于存储记录当前已有loading
let loadingObj = {};
// loading需要显示的基准时间
let loadingDelayShow = 300;
// loading显示的最小时间
let loadingDelayHide = 1000;
let loadingTimer = {};// 默认 loading 配置
const loadingOptionsDefault = {mask: true
}/*** 初始化loading* 基于事件通知实现 loading 的显示与隐藏*/
export const initLoading = (options = '数据加载中...') => {// 监听显示 loading 事件uni.$off('showLoading');// optionsIn是loading的配置,参考showLoading的配置,// 其中key用于存储当前是什么哪一个loading,用于与hideLoading配合使用uni.$on('showLoading', (optionsIn = options, key) => {console.log('---- showLoading ----:', optionsIn, key);// 如果传入的是字符串,则将其作为 titleconst loadingOptions = typeof optionsIn === 'string' ? { ...loadingOptionsDefault, title: optionsIn }: { ...loadingOptionsDefault, ...optionsIn };if (!loadingObj[key]) {loadingObj[key] = {show: false,startTime: Date.now()};}// 如果300ms内又调用了hideloading,则无需显示loadingloadingTimer[key] = setTimeout(() => {if (loadingObj[key] && !loadingObj[key].show) {loadingObj[key].show = true;loadingObj[key].startTime = Date.now();uni.showLoading({...loadingOptions});}}, loadingDelayShow);});// 监听隐藏 loading 事件uni.$off('hideLoading');uni.$on('hideLoading', (key) => {if (loadingObj[key]) {loadingObj[key].show = false;clearTimeout(loadingTimer[key]);}if (isCanHide(key)) {const { startTime } = loadingObj[key];if (Date.now() - startTime >= loadingDelayHide) {resetLoading();} else {setTimeout(() => {if (isCanHide(key)) {resetLoading();}}, loadingDelayHide - (Date.now() - startTime));}}});// 监听重置 loading 事件uni.$off('resetLoading');uni.$on('resetLoading', () => {try {resetLoading();} catch (err){console.log('---- resetLoading ----', err);}});
}// 判断要不要隐藏loading
const isCanHide = (key) => {if (!loadingObj[key].show && Object.keys(loadingObj).length === 1) {return true;}// 或者所有的loading对象的show都是falsefor (const key in loadingObj) {if (loadingObj[key].show) {return false;}}return true;
}const resetLoading = () => {loadingObj = {}uni.hideLoading();
}// 导出事件名称常量
export const LOADING_EVENTS = {SHOW: 'showLoading',HIDE: 'hideLoading',RESET: 'resetLoading'
};// 导出默认对象,包含事件名称常量
export default {LOADING_EVENTS
};

使用方式:

在项目根目录main.js中初始化

import { initLoading } from '@/utils/loading';
initLoading()

在需要的地方调用

// 显示loading
uni.$emit('showLoading', '提交订单中...', 'xxx');// 隐藏loading
uni.$emit('hideLoading', 'xxx'); 

使用注意事项

  • 其中xxx是key,要确保唯一,实在是怕重复的话可以引入第三方的uuid来做
  • 显示与隐藏要配套使用,不然记录的loading不会清空或者状态不会变,会导致问题

小结

这是我的 uni-app项目的loading使用方案,已使用在生产中,还没有发现什么问题,如果后续发现什么问题再做更新吧,解决方案千千万,世上没有最好,只有更好,如果你有更好的解决方案,可以分享出来,或者你发现此方案有什么问题,也可以提出来一起探讨。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/87027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android笔记】记一次 CMake 构建 Filament Android 库的完整排错过程(安卓交叉编译、CMake、Ninja)

写在前面的话,为了保持Sceneform-EQR始终是采用最新的filament,每隔一段时间我都会编译filament,并根据新增内容完善Sceneform-EQR。 现由于更换电脑,环境需重新配置。简单记录下编译出错和解决方式。 Sceneform-EQR 是EQ对谷歌“…

ARM 单片机定义变量绝对地址方法

在ARM单片机中,定义变量到绝对地址通常有以下几种方法(以Keil MDK为例,其他工具链原理类似): 方法1:使用指针强制转换(通用) 直接通过指针访问指定地址: define REGIS…

为何AI推理正推动云计算从集中式向分布式转型

作者简介:Vineeth Varughese是Akamai亚太及日本地区的云产品市场负责人,在云计算、人工智能(AI)及市场进入策略(GTM)领域拥有丰富经验。 传统云平台在利用海量数据训练AI模型方面表现出色,但随着…

ar 导航导览技术如何实现的?室内外融合定位与ar渲染技术深度解析

本文面向:移动开发工程师、AR技术研究者、室内外导航系统产品经理,旨在提供核心问题的参考方案:如何实现室内外无缝切换的精准定位(GPS蓝牙Beacon)虚拟导航路径与实景画面的实时叠加原理。 如需获取ar导航导航技术解决…

电路问题处理:SGMII链路中的AC耦合电容摆放位置

SGMII链路中的AC耦合电容摆放位置 目前是有个板子,其上分别有fpga,fpga的gtx口出sgmii千兆以太网链路,通过高速连接器互联, 通常高速差分链路的AC耦合电容放在靠近接收端位置,如果在同一个板内的话没啥疑惑的直接靠近…

激光雷达 + 视觉相机:高精度位姿测量方案详解

激光雷达 视觉相机:高精度位姿测量方案详解 引言 在航天器交会对接、自动驾驶、机器人导航等领域,位姿(位置姿态)测量的精度和鲁棒性至关重要。单一的传感器(如激光雷达或视觉相机)往往难以满足复杂场景的…

【整数递增加法拆分】2022-4-11

缘由整数拆分问题,但是怎么输出这个数位最多。-编程语言-CSDN问答 void 整数递增加法拆分() {//缘由https://ask.csdn.net/questions/7687667?spm1005.2025.3001.5141int n 0, c 1, f c, t n;string sc "";cin >> n; t n;while (t){if (t &…

Hashcat使用教程:快速上手密码恢复工具

在信息安全领域,密码破解是不可或缺的一环。而 Hashcat,作为当前最强大的密码恢复工具之一,因其高效的性能与灵活的配置广受好评。本文将介绍 Hashcat 的基础用法,帮助新手快速上手,同时遵守合法使用的基本原则。 一、…

萌系盲盒陷维权风暴,Dreams委托David律所已立案,速避雷

美国律所David代理Dreams USA, Inc.发起全新维权案件,维权矛头指向旗下三大萌系盲盒品牌:Sonny Angel、SMISKI和HIPPERS,跨境卖家需提高警惕。 案件基本情况: 起诉时间:2025-6-9 案件号:2025-cv-06422 …

aflplusplus:开源的模糊测试工具!全参数详细教程!Kali Linux教程!(三)

使用 afl-cc 这是 afl-fuzz 的辅助应用程序。它可以作为 gcc 和 clang 的直接替代品,让您使用所需的运行时工具重新编译第三方代码。 1. -help 显示可用选项 afl-cc -help 其他选项同上,这里不再展开叙述。 afl-clang 1. --help 显示可用选项 a…

安卓开发常用框架与库详解

安卓开发常用框架与库详解 安卓应用开发过程中,选择合适的开发框架和第三方库,可以极大提升开发效率、应用性能和代码的可维护性。本文对主流的安卓开发框架和库进行系统梳理,按功能模块分类,涵盖UI开发、网络请求、图片加载、数…

【项目实训#09】智能代码文件助手模式前后端设计与实现

【项目实训#09】智能代码文件助手模式前后端设计与实现 文章目录 【项目实训#09】智能代码文件助手模式前后端设计与实现一、背景简介二、技术方案与架构设计2.1 整体架构2.2 前端技术选型2.3 后端技术选型 三、前端代码替换服务实现3.1 代码替换服务设计3.2 处理生成的代码3.3…

JAVA-springboot 异常处理

SpringBoot从入门到精通-第10章 异常处理 一、异常简介 传统的Java程序都是由try-catch语句捕捉异常,而Spring Boot项目采用了全局异常类的概念------所有方法均将异常抛出,并且专门安排一个类统一拦截并处理这些异常。这样做的好处是可以把异常处理的…

VIC-3D应用指南系列之:DIC数字图像相关技术与热成像(VIC-3D IR System助力热载荷测试)

本篇文章详细讲述了利用VIC-3D 10将数字图像相关DIC数据与红外相机热成像的温度数据相结合的操作流程。核心步骤包括: 相机选型与系统搭建 测试环境配置 VIC-Snap参数设置 双系统标定(DIC与红外) 外部参数计算 测试图像采集 红外…

adoc(asciidoc)转为markdown的方法,把.adoc文件转换为markdown格式

要将.adoc文件转换为markdown格式,可以按照以下步骤操作: 安装必要工具: sudo apt install pandoc asciidoc转换流程: 先将asciidoc转换为docbook格式: asciidoc -b docbook foo.adoc然后将docbook转换为markdown&…

2022mpsPTE岗位笔试题

2022年9月完成了PTE岗位的笔试,并通过了。浅浅的还有一点印象,之前有朋友也想来,就放在这里,供需要的朋友看。 前两个题是关于C语言的。 语言不限,C也可。 一个是输出2到100偶数之和,主要就是调用for循环。…

使用Cursor + Devbox + Uniapp 一站式AI编程开发移动端(App、H5、小程序)

文章目录 前言📖一、工具介绍🛠️1. Cursor:AI驱动的智能代码编辑器2. Devbox:可复现的开发环境管理3. Uniapp:跨平台应用开发框架 二、环境配置与集成🔮1. 安装与配置Devbox2. 配置Cursor连接Devbox环境3.…

[智能客服project] AI提示词配置 | 主协调器 | 闲鱼协议工具

第五章:AI提示词配置 欢迎回来! 在第四章:意图路由器中,我们了解了机器人如何通过IntentRouter确定由哪个专家代理(如PriceAgent或TechAgent)处理用户消息。 但代理被选定后,如何知道该说什么…

CMake 构建系统概述

关键要点 研究表明,CMake 是一种强大的跨平台构建系统,广泛用于 C 项目。证据倾向于认为,CMake 通过生成本地构建文件(如 Makefile、Visual Studio 项目)简化软件构建。它似乎可能支持多种平台,包括 Windo…

如何顺利将电话号码转移到新iPhone?

当您升级到新 iPhone 时,您需要做的第一件事就是转移您的电话号码。幸运的是,以目前的技术,很容易解决如何将电话号码转移到新iPhone上。此外,传输过程也得到了简化。您可以轻松地将旧手机更换为新 iPhone,而不会丢失任…