Table of Contents
2. After encapsulation
Home Web Front-end Vue.js Parse the encapsulation request of axios in vue (with step code)

Parse the encapsulation request of axios in vue (with step code)

Aug 10, 2022 am 10:05 AM
vue axios

1. Introduction

axios is a lightweight HTTP client that performs HTTP requests based on the XMLHttpRequest service, supports rich configuration, supports Promise, and supports browsing Server side and Node.js side. Since Vue2.0, Youda announced that it will cancel the official recommendation of vue-resource and recommend axios instead. Now axios has become the first choice for most Vue developers. (If you are not familiar with axios, you can view its API here.) [Related recommendations: vue.js video tutorial]

Before encapsulating, let’s take a look at it first, without encapsulation In this case, what an axios request looks like in an actual project.

It probably looks like this:

axios('http://localhost:3000/data', {
  method: 'GET',
  timeout: 1000,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'xxx',
  },
  transformRequest: [function (data, headers) {
    return data;
  }],
  // 其他请求配置...
})
.then((data) => {
  // todo: 真正业务逻辑代码
  console.log(data);
}, (err) => {
  if (err.response.status === 401) {
  // handle authorization error
  }
  if (err.response.status === 403) {
  // handle server forbidden error
  }
  // 其他错误处理.....
  console.log(err);
});
Copy after login

You can see that in this code, the page code logic is only on line 15, and a large block of request configuration above The code and a large chunk of response error handling code below have almost nothing to do with the page function, and these contents are similar in every request, and some parts are even exactly the same.

2. After encapsulation

1. Encapsulation steps

The essence of encapsulation is to add various things outside the content to be encapsulated, and then put them It is presented to users as a new whole to achieve expansion and ease of use.

Encapsulationaxios What needs to be done is to configure the configuration common to all HTTP requests on axios in advance, reserve the necessary parameters and interfaces, and then use it as a new The axios returns.

The directory structure is as follows (generated by Vue-cli 3.0):

##|--public/

|--mock/
| |--db.json # My new interface simulation data
|--src/
| |--assets/
| |--components/
| |--router/
| |--store/
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...

2. Package target

on the Home page , making an axios request is as simple as calling a method with only a few parameters, so I can focus on the business code.

1. Encapsulate axios into a separate file

    Create the utils/http.js file under src
  •   cd src
      mkdir utils
      touch http.js
    Copy after login
    Introducing axios
  •   // src/utils/http.js
      import axios from 'axios';
    Copy after login
    Create a class
  •   //src/utils/http.js
      //...
      class NewAxios {
      
      }
    Copy after login
    Configure different request addresses for different environments
Configure different

baseURL according to process.env.NODE_ENV , so that the project can automatically switch the request host address in different environments by simply executing the corresponding packaging command.

// src/utils/http.js

//...
const getBaseUrl = (env) => {
  let base = {
    production: '/',
    development: 'http://localhost:3000',
    test: 'http://localhost:3001',
  }[env];
  if (!base) {
    base = '/';
  }
  return base;
};

class NewAxios {
  constructor() {
    this.baseURL = getBaseUrl(process.env.NODE_ENV);
  }
}
Copy after login

    Configuring the timeout

timeout attribute, I usually set it to 10 seconds.

// src/utils/http.js

//...
class NewAxios {
  constructor() {
    //...
    this.timeout = 10000;
  }
}
Copy after login

    Configuration to allow carrying credentials

widthCredentials property is set to true

// src/utils/http.js

//...
class NewAxios {
  constructor() {
    //...
    this.withCredentials = true;
  }
}
Copy after login

    Create a method request
on the instance of this class. In the

request method, create a new axios instance, receive the request configuration parameters, process the parameters, add configuration, and return the axios instance The request result (a promise object).

You can also directly use the default exported axios instance without creating it, and then put all configurations on it, but in this way the entire project will share one axios instance. Although this is sufficient for most projects, the request and response structures of different service addresses in some projects may be completely different. In this case, sharing one instance cannot support it. So in order to make the encapsulation more versatile and flexible, I will use the

create method of axios so that each request is a new axios instance.

// src/utils/http.js

//...
class NewAxios {
  //...
  request(options) {
    // 每次请求都会创建新的axios实例。
    const instance = axios.create();
    const config = { // 将用户传过来的参数与公共配置合并。
      ...options,
      baseURL: this.baseURL,
      timeout: this.timeout,
      withCredentials: this.withCredentials,
    };
    // 配置拦截器,支持根据不同url配置不同的拦截器。
    this.setInterceptors(instance, options.url);
    return instance(config); // 返回axios实例的执行结果
  }
}
Copy after login

Because the interceptor configuration content is relatively large, it is encapsulated into an internal function.

    Configuring the request interceptor
All modifications to the request parameters before sending the request are configured here. For example, uniformly add token credentials, uniformly set languages, uniformly set content types, specify data formats, etc. Remember to return this configuration after finishing, otherwise the entire request will not proceed.

I will configure a

token here.

// src/utils/http.js

//...
class NewAxios {
  //...
  // 这里的url可供你针对需要特殊处理的接口路径设置不同拦截器。
  setInterceptors = (instance, url) => { 
    instance.interceptors.request.use((config) => { // 请求拦截器
      // 配置token
      config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || '';
      return config;
    }, err => Promise.reject(err));
  }
  //...
}
Copy after login

    Configuring the response interceptor
Perform a round of pre-processing of the response data before the request's

then or catch processing deal with. For example, filtering response data, and more importantly, unified error processing for various response error codes, network disconnection processing, etc.

I will judge 403 and disconnection here.

// src/utils/http.js

//...
class NewAxios {
  //...
  setInterceptors = (instance, url) => {
    //...
    instance.interceptors.response.use((response) => { // 响应拦截器
      // todo: 想根据业务需要,对响应结果预先处理的,都放在这里
      console.log();
      return response;
    }, (err) => {
      if (err.response) { // 响应错误码处理
        switch (err.response.status) {
          case '403':
            // todo: handler server forbidden error
            break;
            // todo: handler other status code
          default:
            break;
        }
        return Promise.reject(err.response);
      }
      if (!window.navigator.online) { // 断网处理
        // todo: jump to offline page
        return -1;
      }
      return Promise.reject(err);
    });
  }
  //...
}
Copy after login

In addition, in the interceptor, it is also suitable to place buffering effects such as loading: Display loading in the request interceptor and remove loading in the response interceptor. In this way, all requests will have a unified loading effect.

    Export new instances by default
  •   // src/utils/http.js
      
      //...
      export default new NewAxios();
    Copy after login

The final complete code is as follows:

// src/utils/http.js

import axios from 'axios';

const getBaseUrl = (env) => {
  let base = {
    production: '/',
    development: 'http://localhost:3000',
    test: 'http://localhost:3001',
  }[env];
  if (!base) {
    base = '/';
  }
  return base;
};

class NewAxios {
  constructor() {
    this.baseURL = getBaseUrl(process.env.NODE_ENV);
    this.timeout = 10000;
    this.withCredentials = true;
  }

  // 这里的url可供你针对需要特殊处理的接口路径设置不同拦截器。
  setInterceptors = (instance, url) => {
    instance.interceptors.request.use((config) => {
      // 在这里添加loading
      // 配置token
      config.headers.AuthorizationToken = localStorage.getItem('AuthorizationToken') || '';
      return config;
    }, err => Promise.reject(err));

    instance.interceptors.response.use((response) => {
      // 在这里移除loading
      // todo: 想根据业务需要,对响应结果预先处理的,都放在这里
      return response;
    }, (err) => {
      if (err.response) { // 响应错误码处理
        switch (err.response.status) {
          case '403':
            // todo: handler server forbidden error
            break;
            // todo: handler other status code
          default:
            break;
        }
        return Promise.reject(err.response);
      }
      if (!window.navigator.online) { // 断网处理
        // todo: jump to offline page
        return -1;
      }
      return Promise.reject(err);
    });
  }

  request(options) {
    // 每次请求都会创建新的axios实例。
    const instance = axios.create();
    const config = { // 将用户传过来的参数与公共配置合并。
      ...options,
      baseURL: this.baseURL,
      timeout: this.timeout,
      withCredentials: this.withCredentials,
    };
    // 配置拦截器,支持根据不同url配置不同的拦截器。
    this.setInterceptors(instance, options.url);
    return instance(config); // 返回axios实例的执行结果
  }
}

export default new NewAxios();
Copy after login

Now

axios Encapsulation is 80% complete. We still need to further combine axios with the interface and encapsulate it one layer further to achieve the encapsulation goal I set at the beginning.

3. Use the new axios packaging API

  • 在 src 目录下新建 api 文件夹。把所有涉及HTTP请求的接口统一集中到这个目录来管理。
  • 新建 home.js。我们需要把接口根据一定规则分好类,一类接口对应一个js文件。这个分类可以是按页面来划分,或者按模块等等。为了演示更直观,我这里就按页面来划分了。实际根据自己的需求来定。
  • 使用新的 axios 封装API(固定url的值,合并用户传过来的参数),然后命名导出这些函数。
// src/api/home.js 

import axios from '@/utils/http';
export const fetchData = options => axios.request({
  ...options,
  url: '/data',
});
export default {};
Copy after login

在 api 目录下新建 index.js,把其他文件的接口都在这个文件里汇总导出。

 // src/api/index.js
  
  export * from './home';
Copy after login

这层封装将我们的新的axios封装到了更简洁更语义化的接口方法中。

现在我们的目录结构长这样:

|--public/
|--mock/
| |--db.json # 接口模拟数据
|--src/
| |--api/ # 所有的接口都集中在这个目录下
| |--home.js # Home页面里涉及到的接口封装在这里
| |--index.js # 项目中所有接口调用的入口
| |--assets/
| |--components/
| |--router/
| |--store/
| |--utils/
| |--http.js # axios封装在这里
| |--views/
| |--Home.Vue
| |--App.vue
| |--main.js
| |--theme.styl
|--package.json
|...

4.使用封装后的axios

现在我们要发HTTP请求时,只需引入 api 下的 index.js 文件就可以调用任何接口了,并且用的是封装后的 axios。

// src/views/Home.vue

<template>
  <div class="home">
    <h1>This is home page</h1>
  </div>
</template>

<script>
// @ is an alias to /src
import { fetchData } from &#39;@/api/index&#39;;

export default {
  name: &#39;home&#39;,
  mounted() {
    fetchData()  // axios请求在这里
      .then((data) => {
        console.log(data);
      })
      .catch((err) => {
        console.log(err);
      });
  },
};
</script>
Copy after login

axios请求被封装在fetchData函数里,页面请求压根不需要出现任何axios API,悄无声息地发起请求获取响应,就像在调用一个简单的 Promise 函数一样轻松。并且在页面中只需专注处理业务功能,不用被其他事物干扰。

The above is the detailed content of Parse the encapsulation request of axios in vue (with step code). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1268
29
C# Tutorial
1243
24
How to use bootstrap in vue How to use bootstrap in vue Apr 07, 2025 pm 11:33 PM

Using Bootstrap in Vue.js is divided into five steps: Install Bootstrap. Import Bootstrap in main.js. Use the Bootstrap component directly in the template. Optional: Custom style. Optional: Use plug-ins.

How to add functions to buttons for vue How to add functions to buttons for vue Apr 08, 2025 am 08:51 AM

You can add a function to the Vue button by binding the button in the HTML template to a method. Define the method and write function logic in the Vue instance.

How to use watch in vue How to use watch in vue Apr 07, 2025 pm 11:36 PM

The watch option in Vue.js allows developers to listen for changes in specific data. When the data changes, watch triggers a callback function to perform update views or other tasks. Its configuration options include immediate, which specifies whether to execute a callback immediately, and deep, which specifies whether to recursively listen to changes to objects or arrays.

What does vue multi-page development mean? What does vue multi-page development mean? Apr 07, 2025 pm 11:57 PM

Vue multi-page development is a way to build applications using the Vue.js framework, where the application is divided into separate pages: Code Maintenance: Splitting the application into multiple pages can make the code easier to manage and maintain. Modularity: Each page can be used as a separate module for easy reuse and replacement. Simple routing: Navigation between pages can be managed through simple routing configuration. SEO Optimization: Each page has its own URL, which helps SEO.

React vs. Vue: Which Framework Does Netflix Use? React vs. Vue: Which Framework Does Netflix Use? Apr 14, 2025 am 12:19 AM

Netflixusesacustomframeworkcalled"Gibbon"builtonReact,notReactorVuedirectly.1)TeamExperience:Choosebasedonfamiliarity.2)ProjectComplexity:Vueforsimplerprojects,Reactforcomplexones.3)CustomizationNeeds:Reactoffersmoreflexibility.4)Ecosystema

How to return to previous page by vue How to return to previous page by vue Apr 07, 2025 pm 11:30 PM

Vue.js has four methods to return to the previous page: $router.go(-1)$router.back() uses &lt;router-link to=&quot;/&quot; component window.history.back(), and the method selection depends on the scene.

How to reference js file with vue.js How to reference js file with vue.js Apr 07, 2025 pm 11:27 PM

There are three ways to refer to JS files in Vue.js: directly specify the path using the &lt;script&gt; tag;; dynamic import using the mounted() lifecycle hook; and importing through the Vuex state management library.

How to use vue traversal How to use vue traversal Apr 07, 2025 pm 11:48 PM

There are three common methods for Vue.js to traverse arrays and objects: the v-for directive is used to traverse each element and render templates; the v-bind directive can be used with v-for to dynamically set attribute values ​​for each element; and the .map method can convert array elements into new arrays.

See all articles