sequence

In the background management project, the response speed of interface requests depends on many factors, such as network, bandwidth, number of simultaneous requests ===, can not be timely response to the request results on the page, and we need to tell the user, the data is loading, you need to wait, have a cup of tea. At this point you need to loading, but it’s not just one request in a project, write each one loading? Maybe some people do, but I’m lazy! I just want to write a global loading when he is needed he comes out, when he is not needed he leaves 🤣 he comes in —-

Global loading

Involves knowledge of VUE (a little bit –), VUex, AXIos interceptor, vue-Router interceptor

Create a new load.js file (ps: wherever you can find it! Nonsense 🐛)

  // Introduce store, i.e. Vuex
  import store from '.. /store/index'
  // Declare a variable for counting
  let loadingNum = 0

  const startLoading = () = >{
    // Do not load requests initiated on the home page (this is because another home screen in the project does not need this global loading, if not you can directly remove!)
    if (global.location.hash ! = ='#/home') {
      loadingNum ++
      store.commit('setChangeLoading'.true)}}const endLoading = () = >{
  	// Here is the same as above
    if (global.location.hash ! = ='#/home') {
      loadingNum --
      
      // This is purely to prevent the variable from becoming negative in extreme cases. (Of course, this could be optimized, but I think it's more obvious!)
      loadingNum = loadingNum < 0 ? 0 : loadingNum
      if(! loadingNum) { store.commit('setChangeLoading'.false)}}}// Reset the function
  const resetLoading = (store) = >{
    // Reset loading each time the route changes
    loadingNum = 0
    store.commit('setChangeLoading'.false)}// Export the function
  export default {
    startLoading,
    endLoading,
    resetLoading
  }

Copy the code

Vuex configuration

Since it is global, it must have a local state. No, there is no need to use vuEX in the project. So what’s not there? LocalStorage, sessionStorage is the same thing but it’s a global variable.

// state
state: {
  loadingState: false
},
// Write a setChangeLoading function of the same name in mutations
mutations: {
  setChangeLoading(state, data) {
    state.loadingState = data
  }
}
Copy the code

Vue-router Indicates the configuration of the route interceptor

Here mainly to page reset switch loading state, global routing after the change, the user is not concerned about data if there is any response, if a user in a routing load data, data response time is long, when the user switch routing data is not loaded, and launched a new request. Global loading is affected by historical routes.

// Remember to introduce load.js
import loading from '.. /utils/loading'

// Create a global routing front guard
router.beforeEach((to, from, next) = > {
  // Remember to introduce load.js
  // I don't care what the three parameters are. If the route changes, I will reset global loading
  loading.resetLoading()
})
Copy the code

Axios interceptor configuration

If you understand the interceptor, you should know what to do. 1. Global loading is closed when the request is loaded or an error occurs

// This file is inside the axios file you encapsulated


// 1. Introduce loading, store
import loading from '.. /utils/loading'
import store from '.. /store'


// Request the interceptor
service.interceptors.request.use(async (config) => {
  // Start the request load
  loading.startLoading()
  
  return config
}, err= > {
  // Error cleanup occurred
  loading.endLoading()
  return Promise.reject(err)
})


// Respond to interceptors
service.interceptors.response.use(response= > {
  // Clean up after loading
  loading.endLoading()
}, err= > {
  // Error cleanup occurred
  loading.endLoading()
  return Promise.reject(handleError(err));
});
Copy the code

What if I want some requests not to load global loading? Now that we have interceptors, isn’t that easy?

Global loading does not loadin this array according to the URL match
const loadingWhitelist = [
  '/place/xxx/12121'
]
// Check whether the specified URL is included
function isLoadingWhite (url) {
  // The indexOf() method returns the first occurrence of a specified string value in the string. Returns -1 if no matching string is found.
  return loadingWhitelist.some(item= > { returnurl.indexOf(item) ! = = -1})}// Request the interceptor
service.interceptors.request.use(async (config) => {

  / / judging loading global loading (config contains the configuration information and request information, specific can print to look at)
  if(! isLoadingWhite(config.url)) { loading.startLoading() }return config
}, err= > {
  loading.endLoading()
  return Promise.reject(err)
})
Copy the code

Used within app.vue

<template>
  <div id="app">
    <router-view/>
    
    <el-col class="loading"
            v-show="$store.state.loadingState"
            element-loading-text="Loading..."
            element-loading-spinner="el-icon-loading"
            element-loading-background="Rgba (0, 0, 0, 0.5)"
            v-loading="$store.state.loadingState">
    </el-col>
  </div>
</template>
<script>
  export default {
    name: 'App'
  }
</script>
<style lang="stylus">
  #app{
  .loading {
      position absolute
      top: 0
      left 0
      width 100%
      height 100vh
      z-index 999999
      background rgba(94.171.198.0.1)}}</style>

Copy the code

In fact, I am in the layout of the main layout file to use!

At the end

Nothing is 100% for everyone. This is written more to write global loading implementation ideas, so copying may be problematic. If you want to use it, you need to use your own understanding. Thank you very much!