【Vue实战】Vuex 和 Axios 拦截器设置全局 Loading

目录

1. 效果图

 2. 思路分析

 2.1 实现思路

2.2 可能存在的问题

2.2.1 并发请求管理

2.2.2 请求快速响应和缓存带来的问题

3. 代码实现

4. 总结 


1. 效果图

如下图所示,当路由变化或发起请求时,出现 Loading 等待效果,此时页面不可见。当路由跳转结束或请求结束时,Loading效果隐藏,页面可见。

 2. 思路分析

接下来从思路和难点入手分析,最终代码实现,解决问题。

 2.1 实现思路

(1) 需要有一个 Loading.vue 组件,可以自己写,也可以用组件库中的组件。

(2) 创建 vuex,通过 vuex store 来管理一个 loading 状态。

(3) 需要在 store 中定义一个计数器,用来追踪正在请求的数量。

(4) 使用 Axios 拦截器,在每次请求开始的时候增加计数器,在请求完成的时候减少计数器。

(5) 根据计数器的值来控制 loading 状态,进而控制 Loading.vue 组件的显示隐藏。

2.2 可能存在的问题

2.2.1 并发请求管理

描述:当应用程序中有多个并发请求时,简单的开始和结束 loading 状态的方式可能会导致 loading 状态提前结束或不正确地显示。例如,如果在 endloading  被调用时还有其他请求未完成,loading 状态应该保持为 true。

参考方法:使用计数器追踪请求数量,如上述所说,Vuex store 中引入一个计数器来追踪正在进行中的请求数量。每次发起请求时增加计数器,请求完成后减少计数器。只有当所有请求都完成后(即计数器归零),才将 loading 置为 false。

2.2.2 请求快速响应和缓存带来的问题

描述:由于网络速度较快或浏览器缓存的原因,某些请求可能会非常快地完成,导致 loading 状态几乎不显示。此外,浏览器可能会从缓存中获取资源,从而绕过了正常的请求流程,使得 loading 状态没有机会被触发。

参考方法:在 endLoading 中引入一个最小延迟(我设置的 300 毫秒)。这样即使请求很快完成,loading 指示器也会显示足够长的时间让用户注意到。可以使用 setTimeOut 来实现这一功能。

3. 代码实现

(1) 如果没有就先下载 Axios 和 vuex。(我是在创建项目的时候就已经下载好了)

下载命令

npm install vuex --savenpm install axios --save

(2) 创建 store 文件,并在其中创建 index.js 文件来定义 Vuex store。然后在主文件 main.js 中引入并使用它。

创建文件夹

/store/index.js 

// 引入 Vue 和 Vuex 库
import Vue from 'vue';
import Vuex from 'vuex';// 使用 Vuex 插件
Vue.use(Vuex);// 创建 Vuex Store 实例
const store = new Vuex.Store({// 定义 state,包含应用程序的状态数据state: {isLoading: false, // 当前是否处于加载状态pendingRequests: 0, // 用来追踪并发请求的数量},// 定义 mutations,用于同步地修改 statemutations: {// 增加正在处理的请求数量incrementPendingRequests(state) {state.pendingRequests++;// 如果这是第一个请求,则设置加载状态为 trueif (state.pendingRequests === 1) {state.isLoading = true;}},// 减少正在处理的请求数量decrementPendingRequests(state) {if (state.pendingRequests > 0) {state.pendingRequests--;// 如果所有请求都已完成,则设置加载状态为 falseif (state.pendingRequests === 0) {state.isLoading = false;}}}},// 定义 actions,用于异步操作和触发 mutationsactions: {// 开始加载状态,通过调用 mutation 增加请求数量startLoading({ commit }) {commit('incrementPendingRequests');},// 结束加载状态,通过调用 mutation 减少请求数量endLoading({ commit }) {commit('decrementPendingRequests');},// 延迟结束加载状态,在指定时间后调用 endLoading actiondelayedEndLoading({ dispatch }, delay = 0) {setTimeout(() => {dispatch('endLoading');}, delay); // 默认延迟时间为 0 毫秒}},// 定义 getters,用于从 state 中派生出一些状态getters: {// 获取当前的加载状态isLoading: state => state.isLoading}
});// 导出 store 实例,以便在应用程序中使用
export default store;

详细注释已在代码中呈现 ↑ ↑ ↑ 

main.js 文件引入 

(3) 创建 axios 文件夹以及相关文件(/api/apiClient.js),添加相应拦截器和请求拦截器,在这里面下文章。

创建文件夹

apiClient.js 文件

// 引入 Axios 库和 Vuex store 实例
import axios from 'axios';
import store from '../store'; // 创建自定义 Axios 实例,用于发起 HTTP 请求
const apiClient = axios.create({baseURL: process.env.VUE_APP_API_URL, // 使用环境变量设置基础 URL,方便跨环境配置timeout: 1000, // 设置请求超时时间为 1 秒headers: { 'Content-Type': 'application/json' } // 设置默认请求头为 JSON 格式
});// 添加请求拦截器,拦截所有发出的请求
apiClient.interceptors.request.use(config => {// 每次请求开始时,调用 Vuex store 的 startLoading action 开始加载状态store.dispatch('startLoading');// 返回配置对象,允许请求继续进行return config;},error => {// 如果请求在发送前发生错误(例如网络错误),调用 endLoading 结束加载状态store.dispatch('endLoading');// 返回一个被拒绝的 Promise,以便处理错误return Promise.reject(error);}
);// 添加响应拦截器,拦截所有接收到的响应
apiClient.interceptors.response.use(response => {// 成功接收到响应后,调用 delayedEndLoading action,在延迟 0.5 秒后结束加载状态store.dispatch('delayedEndLoading', 500); // 成功响应后延迟 0.5 秒结束 loading// 返回响应对象,允许后续处理return response;},error => {// 如果响应失败(例如服务器返回错误码),立即调用 endLoading 结束加载状态store.dispatch('endLoading');// 返回一个被拒绝的 Promise,以便处理错误return Promise.reject(error);}
);// 导出自定义 Axios 实例,以便在整个应用程序中使用
export default apiClient;

详细解说见代码注释 ↑ ↑ ↑ 

(4) 自定义一个 Loading 组件,代码如下。 

Loading.vue 文件

<template><!-- 使用 v-if 指令根据 isLoading 状态显示或隐藏加载指示器 --><div v-if="isLoading" class='base'><!-- 加载动画图片,当 isLoading 为 true 时显示 --><img src="../assets/images/preloader.gif" alt="Loading..."></div>
</template><script>
export default {name: 'Loading',data() {return {}},mounted() {},computed: {isLoading() {// 通过 this.$store.getters 访问 Vuex store 的 getters,// 并返回 isLoading 状态,以控制加载指示器的显示与否return this.$store.getters.isLoading;}}
}
</script><style scoped>
body {background-color: white; font-size: 12px;        
}/* 加载指示器容器样式 */
.base {position: absolute;     top: 50%;               left: 50%;              transform: translate(-50%, -50%);z-index: 9999;          
}
</style>

(5) 实现路由跳转时 loading 效果的呈现。

只需在 /router/index.js 中添加如下代码

// 全局前置守卫
router.beforeEach((to, from, next) => {// 开始加载状态store.dispatch('startLoading');// 继续导航next();
});// 后置钩子
router.afterEach(() => {// 这里可以设置一个短暂的延迟来模拟loading效果,或者直接结束loadingsetTimeout(() => {store.dispatch('endLoading');}, 300); // 可选的延迟时间
});

(6) 在 App.vue 入口文件,放置 Loading.vue组件,当 store 中的 loading 为 true 时,就用Loading.vue组件遮住页面,达到加载中的效果。

App.vue文件

<template><div id="app" :class="{ 'is-loading': $store.getters.isLoading }"><router-view /><Loading /> </div>
</template><script>
import Loading from './components/Loading.vue'
export default {name: 'App',components: {Loading,}
}
</script><style>
*{margin: 0;padding: 0;}
li{list-style:none}
a{text-decoration:none}
#app{height: 100vh;
}
#app.is-loading::before {content: '';position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: white;z-index: 9998; /* 确保它在所有元素之上但低于loading组件 */pointer-events: none; /* 不阻止点击事件传递到下面的loading组件 */
}</style>

注意: 

Loading.vue组件需要将页面遮住,需要提一下的就是层级的问题注意一下。

 (7) 然后在页面请求接口或则路由跳转时,就会出现 loading 效果

4. 总结 

最主要的就是vuex的store中的部分逻辑,以及相应拦截器和请求拦截器调用store中的,总结一下实现步骤吧。(1) 引入必要的库  (2) 创建 Vuex Store  (3) 配置 Axios 实例  (4) 创建加载组件  (5) 将组件集成到应用

如果以上内容对你有用的话不妨点赞、关注+收藏,防止下次迷路😀。

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

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

相关文章

Github配置ssh key,密钥配对错误怎么解决?

解决密钥配对的方案如下&#xff1a; 方法一、最有效的方案&#xff1a;重新配置&#xff0c;验证 SSH 密钥是否已添加到 GitHub 确保您的 SSH 密钥已经正确添加到了 GitHub 账户中。您可以打开命令行控制台&#xff08;cmd/powerShell都可以&#xff09;&#xff0c;按照以下…

Java基础知识(六) -- 常用类

1.包装类 1.1 概述 Java提供了两个类型系统&#xff0c;基本类型与引用类型&#xff0c;使用基本类型在于效率&#xff0c;但当使用只针对对象设计的API或新特性(例如泛型)&#xff0c;那么基本数据类型的数据就需要用包装类来包装。 序号基本数据类型包装类&#xff08;java…

fbx 环境搭建

python 3.7 3.8 版本支持 https://github.com/Shiiho11/FBX-Python-SDK-for-Python3.x 只有python3.7 https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2020-3 scipy安装&#xff1a; python安装scipy_scipy1.2.1库怎么安装-CSDN博客 smpl 2 fbx…

【Linux】深入理解文件系统(超详细)

目录 一.磁盘 1-1 磁盘、服务器、机柜、机房 &#x1f4cc;补充&#xff1a; &#x1f4cc;通常网络中用高低电平&#xff0c;磁盘中用磁化方向来表示。以下是具体说明&#xff1a; &#x1f4cc;如果有一块磁盘要进行销毁该怎么办&#xff1f; 1-2 磁盘存储结构 ​编辑…

【硬件介绍】Type-C接口详解

一、Type-C接口概述 Type-C接口特点&#xff1a;以其独特的扁头设计和无需区分正反两面的便捷性而广受欢迎。这种设计大大提高了用户的使用体验&#xff0c;避免了传统USB接口需要多次尝试才能正确插入的问题。Type-C接口内部结构&#xff1a;内部上下两排引脚的设计虽然可能不…

Linux第二课:LinuxC高级 学习记录day02

2.4、shell中的特殊字符 2.4.4、命令置换符 或者 $() 反引号&#xff1a;esc下面的按键&#xff0c;英文状态下直接按 功能&#xff1a;将一个命令的输出作为另一个命令的参数 echo 不会认为hostname是一个命令 加上 之后&#xff0c;先执行hostname&#xff0c;拿到主机名…

图生生AI描述生图:一句话生成蛇年海报素材

2025年春晚吉祥物“巳升升”的亮相&#xff0c;引发了广泛讨论。其整体造型参考甲骨文中的“巳”字&#xff0c;以青绿色为主调&#xff0c;象征春意盎然、蓬勃生机。从头部轮廓、脸颊螺旋形状到五官设计&#xff0c;都蕴含着丰富的传统文化元素。巳升升的亮相&#xff0c;春节…

如何提高自动化测试覆盖率和效率

用ChatGPT做软件测试 在现代软件开发中&#xff0c;自动化测试已经成为保证软件质量的重要手段。然而&#xff0c;在实践中&#xff0c;自动化测试的覆盖率和效率常常受到限制&#xff0c;导致潜在缺陷未能及时发现或测试资源浪费。因此&#xff0c;提升自动化测试的覆盖率和效…

OpenCV相机标定与3D重建(54)解决透视 n 点问题(Perspective-n-Point, PnP)函数solvePnP()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 根据3D-2D点对应关系找到物体的姿态。 cv::solvePnP 是 OpenCV 库中的一个函数&#xff0c;用于解决透视 n 点问题&#xff08;Perspective-n-Po…

KMP前缀表 ≈ find() 函数——28.找出字符串中第一个匹配项的下标【力扣】

class Solution { public: //得到前缀表void getNext(int *next,string needle){int j0;for(int i1;i<needle.size();i){while(j>0 && needle[j]!needle[i]) jnext[j-1];//**j>0**>j0是出口if(needle[i]needle[j]) j;next[i]j;//若写入if中&#xff0c;则该…

前端笔记----

在我的理解里边一切做页面的代码都是属于前端代码。 之前用过qt框架&#xff0c;也是用来写界面的&#xff0c;但是那是用来写客户端的&#xff0c;而html是用来写web浏览器的&#xff0c;相较之下htmlcssJavaScript写出来的界面是更加漂亮的。这里就记录我自个学习后的一些笔…

FairGuard游戏安全2024年度报告

导 读&#xff1a;2024年&#xff0c;国内游戏市场实际销售收入3257.83亿元&#xff0c;同比增长7.53%&#xff0c;游戏用户规模6.74亿人&#xff0c;同比增长0.94%&#xff0c;市场收入与用户规模双双实现突破&#xff0c;迎来了历史新高点。但游戏黑灰产规模也在迅速扩大&…

二 RK3568 固件中打开 ADB 调试

一 usb adb Android 系统,设置->开发者选项->已连接到计算机 打开,usb调试开关打开 通过 usb otg 口连接 开发上位机 (windows/linux) 上位机安装 adb 服务之后 , 通过 cmd/shell: #1 枚举设备 adb devices #2 进入 android shell adb shell # 3 验证上传下载…

深入解析 C++ 类型转换

简介 C 类型转换是开发者必须掌握的重要技能之一, 无论是处理隐式转换还是显式转换, 理解其背后的机制与用法至关重要. 本篇博客旨在从基础到高级全面解析 C 的类型转换, 包括实际开发中的应用场景和性能分析. 自动转换 隐式类型转换 编译器可以在无需明确指示的情况下, 将一…

C++ STL之容器介绍(vector、list、set、map)

1 STL基本概念 C有两大思想&#xff0c;面向对象和泛型编程。泛型编程指编写代码时不必指定具体的数据类型&#xff0c;而是使用模板来代替实际类型&#xff0c;这样编写的函数或类可以在之后应用于各种数据类型。而STL就是C泛型编程的一个杰出例子。STL&#xff08;Standard …

uniapp 抖音小程序 getUserProfile:fail must be invoked by user tap gesture

项目场景&#xff1a; uniapp 抖音小程序 getUserProfile:fail must be invoked by user tap gesture,在实现点击头像需要出发抖音小程序获取用户原生头像的操作中&#xff0c;无论如何也无法触发抖音的原生窗口&#xff01; 问题描述 这个问题我找了很多博主的方法&#xff…

.NET Core NPOI 导出图片到Excel指定单元格并自适应宽度

NPOI&#xff1a;支持xlsx&#xff0c;.xls&#xff0c;版本>2.5.3 XLS&#xff1a;HSSFWorkbook&#xff0c;主要前缀HSS&#xff0c; XLSX&#xff1a;XSSFWorkbook&#xff0c;主要前缀XSS&#xff0c;using NPOI.XSSF.UserModel; 1、导出Excel添加图片效果&#xff0…

SpringCloud微服务:基于Nacos组件,整合Dubbo框架

dubbo和fegin的差异 一、Feign与Dubbo概述 Feign是一个声明式的Web服务客户端&#xff0c;使得编写HTTP客户端变得更简单。通过简单的注解&#xff0c;Feign将自动生成HTTP请求&#xff0c;使得服务调用更加便捷。而Dubbo是一个高性能、轻量级的Java RPC框架&#xff0c;提供了…

c#版本、.net版本、visual studio版本之间的对应关系

最近这几年一直没用过c#开发&#xff0c;都是从事Qt c开发工作&#xff0c;回想一下之前c#还要追溯到2019年&#xff0c;算算时间大概都已过去4&#xff0c;5年了&#xff0c;时间飞快。 2019真是个神奇的数字&#xff0c;vs2019是我用的时间最长的一个IDE&#xff0c;新冠起始…

MySQL数据库基础 === 多表查询

目录 什么是多表查询&#xff1f; 多表查询的基本语法 多表关系 测试数据准备 一对多 多对多 一对一 查询 内连接查询 外连接查询 自连接查询 联合查询 union, union all 子查询 标量子查询 列子查询 行子查询 表子查询 DISTINCT 去重 单列去重 多列去重 …