vuex+axios+element-ui实现页面请求loading操作示例

本文实例讲述了vuex+axios+element-ui实现页面请求loading操作。分享给大家供大家参考,具体如下:

前言

我们在平常写项目的时候,发请求的时候肯定会习惯用一个 loading 遮罩层来防止用户在没拿到数据之前误操作

如果是页面同时只发送一个请求,那么无论是在组件中或者是在 axios 插件中进行请求和响应拦截都可以做到

但是,当一个页面同时要发送多个请求的时候,这么做显然就不行了

因为最先完成的请求会把所有请求的 loading 都给关闭

举个例子,第一个请求的响应时间为 3s ,第二个请求的响应时间为 1s ,两个同时请求的时候,loading 会开始

但是当 1s 后第二个请求完成后,会直接关闭 loading,但是此时第一个请求还没完成,所有这样肯定是不行的

今天就用这篇文章来介绍下我在项目中是怎么应对这种情况的

一、用到的东西

  1. element-ui 的 loading
  2. vuex 的状态管理
  3. axios 的请求拦截和响应拦截

二、实现

其实这个思路很简单,就是通过 vuex 来管理请求的个数,假如用 apiCount 这个变量来代表请求的个数,每次请求的时候打开 loading 并且 apiCount  加一,每次响应完成或者失败的时候都让 apiCount 减一,并且检测 apiCount 变量的值,当为 apiCount=0 的时候,就关闭 loading 就可以了,代码如下:

store.js 代码(用来管理 vuex)

import Vue from "vue";
import Vuex from "vuex";
import { Loading } from "element-ui";
Vue.use(Vuex);
const state = {
 //请求计数
 apiCount: 0,
 //loading实例
 loadingInstance: null,
};
const mutations = {
 /* 打开Loading */
 startLoading(state, msg) {
  state.loadingInstance = Loading.service({
   lock: true,
   text: msg ? msg : "加载中...",
   background: "rgba(0, 0, 0, 0.7)"
  });
 },
 /* 关闭loading */
 closeLoading(state) {
  state.loadingInstance.close();
 },
 /* 更新请求线程池 */
 updateApiCount(state, handle) {
  if (handle == "add") {
   state.apiCount++;
   this.commit("startLoading");
  } else {
   state.apiCount--;
   if (state.apiCount <= 0) {
    this.commit("closeLoading");
   }
  }
 }
};
const store = new Vuex.Store({
 state,
 mutations
});
export default store;

request.js 代码(封装 axios 的文件)

import axios from "axios";
import { Message } from "element-ui";
import store from "../store/index";
import router from "../router/index";
const service = axios.create({
 baseURL: process.env.VUE_APP_BASE_URL,
 timeout: 0
});
service.interceptors.request.use(
 config => {
  store.commit("updateApiCount", "add");
  return config;
 },
 error => {
  store.commit("updateApiCount", "sub");
  Promise.reject(error);
 }
);
service.interceptors.response.use(
 response => {
  store.commit("updateApiCount", "sub");
  return response.data;
 },
 error => {
  store.commit("updateApiCount", "sub");
  return Promise.reject(error);
 }
);
export default service;

好了,这样就做到了请求的时候自动打开 loading,所有的请求结束才会关闭 loading 了,无论同时多少个请求都可以

希望本文所述对大家vue.js程序设计有所帮助。

(0)

相关推荐

  • vue2实现数据请求显示loading图

    一般项目中,有时候会要求,你在数据请求的时候显示一张gif图片,然后数据加载完后,消失.这个,一般只需要在封装的axios中写入js事件即可.当然,我们首先需要在app.vue中,加入此图片.如下: <template> <div id="app"> <loading v-show="fetchLoading"></loading> <router-view></router-view> <

  • Vue 全局loading组件实例详解

    上图不上种,菊花万人捅: loading.js: import './loading.css' let Loading = {} // 避免重复install,设立flag Loading.installed = false Loading.install = function (Vue) { if (Loading.installed) return Vue.prototype.$loading = {} Vue.prototype.$loading.show = () => { // 如果页

  • Vue2.0 http请求以及loading展示实例

    我们需要额外两个依赖vuex 和 axios:(还是接着上一个项目MyFirstProject写) npm i vuex axios -D 首先简单的阐述下http请求 1.main.js 中引入axios import axios from 'axios' Vue.prototype.$http = axios; 2.focus.vue中写个函数获取数据 <template> <div id="focus"> <ul > <li v-for=

  • Vue基于vuex、axios拦截器实现loading效果及axios的安装配置

    准备 利用vue-cli脚手架创建项目 进入项目安装vuex.axios(npm install vuex,npm install axios) axios配置 项目中安装axios模块(npm install axios)完成后,进行以下配置: main.js //引入axios import Axios from 'axios' //修改原型链,全局使用axios,这样之后可在每个组件的methods中调用$axios命令完成数据请求 Vue.prototype.$axios=Axios l

  • vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解

    项目结构,在组件文件夹(components)下新建common文件夹,所用公用组件放里面,本例包含tips和loading两个 一.loading组件 1.loading.vue组件内容如下: 代码: <template> <div class="loading" v-show="loading"> <img src="./loading.gif"> </div> </template>

  • 基于Vue 实现一个中规中矩loading组件

    前言 最近有一个新的项目,UI大佬不知道从哪里找来了一张GIF丢到蓝湖,说作为全局的页面loading ,但是自己想了想,还是选择画一个. 一开始想过用svg,canvas;最终还是选择了css3+js来实现这个效果: gif的缺点挺多,至于为什么又排除了svg和canvas: 是因为css3+js可控性更强,不管是大小还是颜色,还是响应式(我的项目走的vh,vw)那套来适配: 可以借助打包插件,达到loading的大小适配; 效果 UI大佬提供的GIF 实现的效果[在线codesandbox预

  • vue+axios+element ui 实现全局loading加载示例

    实现全局loading加载 分析需求,我们只需要在请求发起的时候开始loading,响应结束的时候关闭loading,就这么简单 对不对? import axios from 'axios'; import { Message, Loading } from 'element-ui'; import Cookies from 'js-cookie'; import router from '@/router/index' let loading //定义loading变量 function st

  • Vue自定义全局Toast和Loading的实例详解

    如果我们的Vue项目中没有用到任何UI框架的话,为了更好的用户体验,肯定会用到loading和toast.那么我们就自定义这两个组件吧. 1.Toast组件 首先,在common下新建global文件夹,存放我们的toast.vue和toast.js两个文件(当然文件的具体位置你可以自行安排). (1). toast.vue <template lang="html"> <div v-if="isShowToast" class="toa

  • vue实现图片加载完成前的loading组件方法

    如下所示: <template> <img :src="url"> </template> <script> export default { props: ['src'], // 父组件传过来所需的url data() { return { url: 'http://www.86y.org/images/loading.gif' // 先加载loading.gif } }, mounted() { var newImg = new Im

  • 详解vue使用vue-layer-mobile组件实现toast,loading效果

    安装vue-layer-mobile // 当前最新版本 1.2.0 npm install vue-layer-mobile // 如新版遇到问题可回退旧版本 npm install vue-layer-mobile@1.0.0 此版本安装后启动会报错,报错提示将css里的display:box改成display:flex; 在main.js里面全局引用 import 'vue-layer-mobile/need/layer.css' import layer from 'vue-layer-

随机推荐