preface

To use loading in a project, you can change a variable in JS or call a method in a Service. For example, Element Ui provides loading in both ways, which has good scalability.

BUT, if you are doing a back-end management project, there is an API that repeats the code like this, EMMM… I can’t accept that. Look how lazy I am wrapping automatic global loading into AXIos in the Vue project.

Also, I see a lot of friends still writing code like this:

/** * This article assumes that the back end returns a relatively standard code, data, message */ api.http('url' , data).then(res => {
    if(res.code === 200) {// Successful operation}else{// error alert, of course, this is just an example, not really alert, but you have to write every request, how tired! alert(res.message) } })Copy the code

The preparatory work

  • A relatively standard onevueProject, optional usevue-cliScaffolding construction;
  • The introduction ofaxiosTheoretically directnpm install axios;
  • Suggestions in the projectsrcCreate one in the directoryutilsDirectory, can be divided into files to write somefilter, public methods, etc… ;
  • inutilsDirectory creationhttp.js(Name it whatever you want, fun, whatever you want.)

OK, the next step is to wrap AXIos in http.js.

Encapsulation axios

I’m going to skip this and go straight to the code

import axios from 'axios'
import store from '.. /store'// Loading calls Store import {getToken} from'@/utils/auth'Const service = axios.create({// API base_URL, local configuration of the proxy, in principle can not use baseURL // baseURL: Process.env.base_api, timeout: 15000, // Request timeout // headers can be set here or created in the request interceptor // headers: {'X-Custom-Header': 'foobar'}}) / / request interceptor service. The interceptors. Request. Use (config = > {/ /!!!!!! The loading effect is triggered here!! store.dispatch('SetLoading'.trueHeaders getToken() && (config.headers[)'token'] = token) // Headers config. Headers ['deviceType'] = 'school_admin_web' 
  returnConfig}, error => {const {response} = error Such as global prompt Promise. Reject (error)}) / / respone interceptor service. The interceptors. Response. Use (response = > {/ /!!!!!! Closed loading!!!!!! store.dispatch('SetLoading'.false)
    
    const res = response.data
    if(res.code ! == 200) {// Some global errors can be made here, so there is no need to write another one for each requestelseAlert (res.message) // Not true alert!returnresponse.data }, error => { // !!! Closed loading!!!!!! store.dispatch('SetLoading'.false) const {response} = error // You can do some operations based on your business, such as forcing a logoutreturn Promise.reject(error)
  }
)

export default service

Copy the code

As you can see, global loading is directly shown in the code above, so we don’t need to talk about it here. For global loading, SetLoading is actually called in the store.

If you have not used Store, please study the documentation for yourself. Store is not explained in detail here.

Use store to control the loading state

Here, assume that you are already familiar with Store and use store modularity (of course, it doesn’t matter if you don’t, it’s up to you). Suppose there is an app Module in the Store directory that corresponds to app.js.

const app = {
  state: {
    requestLoading: 0,
  },
  mutations: {
    SET_LOADING: (state, boolean) => {
      boolean ? ++state.requestLoading : --state.requestLoading
    },
  },
  actions: {
    SetLoading ({ commit }, boolean) {
      commit('SET_LOADING', boolean)
    },
  },
}

export default app

Copy the code

In the REQUEST interceptor in AXIos, I called store SetLoading and changed the value of requestLoading to increment by 1. In response interceptor, I also called Store SetLoading and changed the value of requestLoading to decrease by 1. The whole principle is similar to the garbage collection mechanism. In this way, when multiple requests are concurrent, the loading effect will disappear only after all the requests return results.

Now the focus is only in the requestLoading state of the APP module under store. We can use this to judge the loading effect.

So, the rest of the code, I’m not going to talk about it here,

In your layout layer, you can position the loading of a shadow layer and use the state of the requestLoading to determine whether to show or hide (something like this).

<template>
  <section class="app-main">
    <div class="request-loading" :class="{'request-loading-show' : requestLoading}">
      <div class="loading-module"></div>
    </div>
    <transition name="fade-transform" mode="out-in">
      <router-view/>
    </transition>
  </section>
</template>
<script>
import { mapGetters } from 'vuex'

export default {
  name: 'AppMain', computed: { ... mapGetters(['requestLoading'},} </script> //. Request-loading-showCopy the code

Finally using

Create an API directory under SRC to module all API definitions. For example:

import http from '@/utils/http'

export default {
  add (data) {
    return http({ url: '... ', data: data, method: 'post'})},} // Then call the component normally...Copy the code

conclusion

The loading effect is automatically displayed during the request. When there is an error, the global alert is ready.

Lazy, that is, lazy behavior, does not mean lazy thinking;

Lazy behavior, will promote thinking to achieve lazy…

If there is something wrong, please feel free to mention it

If you have better suggestions, welcome to leave a message to communicate ~