经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue公共loading升级版(处理并发异步差时响应)
来源:cnblogs  作者:波特卡斯D  时间:2023/11/22 16:46:43  对本文有异议

公共loading是项目系统中很常见的场景,处理方式也不外乎三个步骤:
1.通过全局状态管理定义状态值(vuex、pinia等)。
2.在程序主入口监听状态值变化,从而展示/隐藏laoding动画。
3.在请求和相应拦截器中变更状态值。

第一二步骤处理大同小异,但在第三步中,网上很多博文分享的方法是:在请求拦截中展示loading,在响应拦截器中判断收到成功响应时直接隐藏loading,这种方法看似可行但实际过程中却有问题。
例如,假设在第0秒时同时向后台发送了两个异步请求A和B,由于网络或处理逻辑不同,A请求0.5秒秒收到成功响应,B请求2秒才收到。那在第0.5秒,响应拦截器就会把loading状态变更,结束loading动画,但此时B请求还没收到返回。如果用户接下来的操作同时需要A和B请求的数据,提前结束动画会让用户体检变差。

解决思路:
定义一个全局对象来存储每个接口的响应状态,直到每个请求接口都收到响应才变更状态,结束loading动画。因为键名的唯一性,可以使用接口路径(或唯一接口编号)作为键名。请求时添加一个键值对,响应时变更键值,同时遍历对象状态值进行判断

  1. let apiStatusList ={
  2. '/api/a':true,//true请求中
  3. '/api/b':false //false请求完成
  4. }

具体操作如下(以vue3的pinia为例):
定义一个loading.js

  1. import { defineStore } from 'pinia';
  2. export const useLoadStore = defineStore('storeLoading', {
  3. state: () => {
  4. return {
  5. apiStatusList:{},
  6. loading:false, //网络加载状态,true加载中
  7. };
  8. },
  9. actions: {
  10. updateLoadingState(value){
  11. this.loading = value
  12. },
  13. setApiStatusList(value){
  14. this.apiList = value;
  15. }
  16. }
  17. });

拦截器处理:

  1. import axios from 'axios';
  2. import { useLoadStore } from '../stores/loading';
  3. const request = axios.create();
  4. //请求拦截
  5. request.interceptors.request.use(
  6. (config) => {
  7. //公共loading
  8. const loadStore = useLoadStore();
  9. let statusList = { ...loadStore.apiStatusList };
  10. statusList[config.url] = true; //接口赋值为请求中
  11. loadStore.setApiStatusList(statusList);
  12. if (!loadStore.loading) { //判断loading是否正在展示中
  13. loadStore.updateLoadingState(true);
  14. }
  15. return config;
  16. },
  17. (error) => {
  18. return Promise.reject(error);
  19. }
  20. )
  21. //响应拦截
  22. request.interceptors.response.use(
  23. (response) => {
  24. const loadStore = useLoadStore();
  25. let statusList = { ...loadStore.apiStatusList };
  26. statusList[response.config.url] = false; ////接口赋值为请求完成
  27. if (!Object.values(statusList).includes(true)) { //遍历对象,判断接口是否全部返回
  28. if (loadStore.loading) {
  29. loadStore.updateLoadingState(false);
  30. loadStore.setApiStatusList({});
  31. }
  32. } else {
  33. loadStore.setApiStatusList(statusList);
  34. }
  35. },
  36. (error) => {//有接口报错,重置loading
  37. const loadStore = useLoadStore();
  38. if (loadStore.loading) {
  39. loadStore.updateLoadingState(false);
  40. loadStore.setApiStatusList({});
  41. }
  42. }

App.vue监听状态变化

  1. //监听store状态值时需要传入function
  2. watch(()=>loadStore.loading,(newValue, oldValue)=>{
  3. if(newValue){
  4. showLoadingToast({
  5. duration: 0,
  6. forbidClick: true,
  7. });
  8. }else{
  9. closeToast();
  10. }
  11. })

原文链接:https://www.cnblogs.com/zyj-Blogs/p/17844283.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号