vue element admin learning notes - take you to use vue to roll up the background series I (basic chapter)

Article directory

directory structure

api and views

It is suggested that views should be divided according to the business module, and views and api should be one-to-one corresponding to facilitate maintenance. The following picture:

Package axios

axios basic case

const url = 'https://test.youbaobao.xyz:18081/book/home/v2'
axios.get(url, { 
  params: { openId: '1234' },
  // Add a token to http header
  headers: { token: 'abcd' }
}).then(response => {
  console.log(response)
}).catch(err => {
  // Catch the exception thrown by the server, that is, return non-200 requests
  console.log(err)
})

There are two problems in this case:

  • Every request that needs to pass in token needs to add headers object, which will cause a lot of duplicate code
  • Each request needs to define exception handling manually, and the logic of exception handling is mostly consistent. If it is encapsulated as a general exception handling method, then each request needs to be called once

axios.create example

Use axios.create to refactor the whole request:

const url = '/book/home/v2'
const request = axios.create({
  baseURL: 'https://test.youbaobao.xyz:18081',
  timeout: 5000
})
request({
  url, 
  method: 'get',
  params: {
    openId: '1234'
  }
})

First, a function is generated through axios.create, which is an Axios instance. The request is completed by executing this method. The difference between this function and the direct call to axios.get is as follows:

  • The url parameter needs to be passed in. The first parameter of axios.get method is url
  • The method parameter needs to be passed in. The axios.get method already indicates that a get request is initiated

axios request interceptor

The above code completes the function of basic request. The following needs to add token to the headers of http request, and perform white list verification at the same time. For example, / login does not need to add token, and implements asynchronous capture and custom processing:

const whiteUrl = ["/login"];
const url = "/book/home/v2";
const request = axios.create({
  baseURL: "https://test.youbaobao.xyz:18081",
  timeout: 5000
});
// request interceptor 
request.interceptors.request.use(
  // Intercepted axios object
  config => {
    // throw new Error('error...')
    // Leave baseURL empty
    const url = config.url.replace(config.baseURL, "");
    // If there is one in the white list, return to axios directly
    if (whiteUrl.some(wl => url === wl)) {
      return config;
    }
    // When there is no token in the white list, the token is added
    config.headers["token"] = "abcd";
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);
request({
  url,
  method: "get",
  params: {
    openId: "1234"
  }
})
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  });

The core here is to call the request.interceptors.request.use method of axios, which needs to pass in two parameters. The first parameter is the interceptor method, which contains a config parameter. We can modify the config in this method and return it. The second parameter is the exception handling method. We can use promise.request (error) Return the exception to the user for processing, so we can catch the exception through catch for customized processing after the request

axios response interceptor

Next, we will further enhance the functions of axios. We need to ensure that the http statusCode is 200 and the business code is correct in the actual development. In the above case, I defined that when the error code is 0, it means that the business returns normally. If the return value is not 0, it means that the business processing is wrong. At this time, we use request.interceptors.response.use Method defines the response interceptor, which still requires two parameters, similar to the request interceptor. Note that the second parameter mainly deals with exception requests with statusCode other than 200. The source code is as follows:

const whiteUrl = ["/login"];
const url = "/book/home/v2";
const request = axios.create({
  baseURL: "https://test.youbaobao.xyz:18081",
  timeout: 5000
});
// request interceptor 
request.interceptors.request.use(
  // Intercepted axios object
  config => {
    // throw new Error('error...')
    // Leave baseURL empty
    const url = config.url.replace(config.baseURL, "");
    // If there is one in the white list, return to axios directly
    if (whiteUrl.some(wl => url === wl)) {
      return config;
    }
    // When there is no token in the white list, the token is added
    config.headers["token"] = "abcd";
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// Response interceptor
request.interceptors.response.use(
  response => {
    const res = response.data;
    if (res.error_code != 0) {
      // Request failed with error message
      alert(res.msg);
      return Promise.reject(new Error(res.msg));
    } else {
      // Request succeeded, return data
      return res;
    }
  },
  error => {
    return Promise.reject(error);
  }
);

request({
  url,
  method: "get",
  params: {
    openId: "1234"
  }
})
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  });

Source code analysis of request Library

With the above foundation, it's very easy for us to look at the source code of the request library

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})

service.interceptors.request.use(
  config => {
    // If there is a token, it is attached to the http header
    if (store.getters.token) {
      config.headers['X-Token'] = getToken()
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data

    if (res.code !== 20000) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
      // Judge the scenario of token failure
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // If the token fails, a confirmation dialog box will pop up. After the user clicks, clear the token and return to the login page
        MessageBox.confirm('Token Invalid, log in again or not', 'Confirm logout', {
          confirmButtonText: 'Re login',
          cancelButtonText: 'cancel',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            // To re instantiate the Vue router object and avoid bug s
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

router-view

The created and edited pages use the same component. By default, when the two pages are switched, the created or mounted hooks of vue will not be triggered. The official says that you can do this through the change of watch $route, but it's really troublesome. Later, it was found that you can simply add a unique key to the router view to ensure that the trigger hook will be re rendered when the route is switched. It's so much simpler.

<router-view :key="key" />
computed: {
  key() {
    return this.$route.path
  }
}

Reference link

[Xiaomu reading] management background
Touch your hand, take you to the backstage series I (basic)

Published 47 original articles, won praise and 997 visitors
Private letter follow

Keywords: axios Vue

Added by guitarlvr on Tue, 18 Feb 2020 15:19:57 +0200