"Vue Interview Questions" Has axios been packaged in the Vue project? What is the main package?

insert image description here

1. What is axios

axiosis a lightweight HTTPclient

Execute requests based on XMLHttpRequestservices HTTP, support rich configuration, support Promise, support browser and Node.jsclient . Since Vue2.0, Youda announced that it will cancel the official recommendation vue-resourceof , and recommend it instead axios. Now axiosit has become Vuethe first choice of most developers

characteristic

  • Created from the browserXMLHttpRequests
  • from node.jscreate httprequest
  • support PromiseAPI
  • Intercept requests and responses
  • Transform request data and response data
  • cancel request
  • Automatically convert JSONdata
  • Client Support DefenseXSRF

basic use

Install

// 项目中安装
npm install axios --S
// cdn 引入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

import

import axios from 'axios'

send request

axios({
    
            
  url:'xxx',    // 设置请求的地址
  method:"GET", // 设置请求方法
  params:{
    
          // get请求使用params进行参数凭借,如果是post请求用data
    type: '',
    page: 1
  }
}).then(res => {
    
      
  // res为后端返回的数据
  console.log(res);   
})

concurrent requestsaxios.all([])

function getUserAccount() {
    
    
    return axios.get('/user/12345');
}

function getUserPermissions() {
    
    
    return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
    .then(axios.spread(function (res1, res2) {
    
     
    // res1第一个请求的返回的内容,res2第二个请求返回的内容
    // 两个请求都执行完成才会执行
}));

2. Why package

axiosThe API is very friendly, you can easily use it directly in your project.

However, as the scale of the project increases, every time HTTPa request is initiated, operations such as setting the timeout period, setting the request header, judging which request address to use according to the project environment, error handling, etc., need to be written again

This kind of duplication of work not only wastes time, but also makes the code redundant and difficult to maintain. In order to improve our code quality, we should re-encapsulate it in the project axiosbefore using

for example:

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);
});

If each page sends a similar request, it will be too cumbersome to write a bunch of configuration and error handling

At this time, we need to axioscarry out secondary packaging to make it more convenient to use

3. How to package

While encapsulating, you need to negotiate some agreements with the backend, request header, status code, request timeout...

Set the interface request prefix: according to different development, test, and production environments, the prefix needs to be distinguished

Request header: To implement some specific services, some parameters must be carried before the request can be made (for example: membership business)

Status code: According to the difference returned by the interface status, different services are executed, which needs to be agreed with the backend

Request method: re-encapsulate according to methods such as get, etc., which is more convenient to usepost

Request Interceptor: Determine which requests can be accessed according to the request header settings of the request

Response interceptor: This block is to judge and execute different businesses according to the status code returned by the backend`

Set the interface request prefix

Use nodeenvironment variables to make judgments to distinguish development, testing, and production environments

if (process.env.NODE_ENV === 'development') {
    
    
  axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {
    
    
  axios.defaults.baseURL = 'http://prod.xxx.com'
}

When debugging locally, you also need to vue.config.jsconfigure proxy forwarding in the file devServerto achieve cross-domain

devServer: {
    
    
    proxy: {
    
    
      '/proxyApi': {
    
    
        target: 'http://dev.xxx.com',
        changeOrigin: true,
        pathRewrite: {
    
    
          '/proxyApi': ''
        }
      }
    }
  }

Set request headers and timeouts

In most cases, the request headers are fixed, and only in a few cases, some special request headers are required. Here, the universal request headers are used as the basic configuration. When a special request header is required, the special request header is passed in as a parameter to override the basic configuration

const service = axios.create({
    
    
    ...
    timeout: 30000,  // 请求 30s 超时
      headers: {
    
    
        get: {
    
    
          'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
          // 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
        },
        post: {
    
    
          'Content-Type': 'application/json;charset=utf-8'
          // 在开发中,一般还需要单点登录或者其他功能的通用请求头,可以一并配置进来
        }
  },
})

Package request method

First introduce the encapsulated method, and re-encapsulate it into a method in the interface to be called to expose it

// get 请求
export function httpGet({
     
     
  url,
  params = {
     
     }
}) {
    
    
  return new Promise((resolve, reject) => {
    
    
    axios.get(url, {
    
    
      params
    }).then((res) => {
    
    
      resolve(res.data)
    }).catch(err => {
    
    
      reject(err)
    })
  })
}

// post
// post请求
export function httpPost({
     
     
  url,
  data = {
     
     },
  params = {
     
     }
}) {
    
    
  return new Promise((resolve, reject) => {
    
    
    axios({
    
    
      url,
      method: 'post',
      transformRequest: [function (data) {
    
    
        let ret = ''
        for (let it in data) {
    
    
          ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
        }
        return ret
      }],
      // 发送的数据
      data,
      // url参数
      params

    }).then(res => {
    
    
      resolve(res.data)
    })
  })
}

Put the encapsulated method in a api.jsfile

import {
    
     httpGet, httpPost } from './http'
export const getorglist = (params = {
     
     }) => httpGet({
    
     url: 'apps/api/org/list', params })

can be called directly from the page

// .vue
import {
    
     getorglist } from '@/assets/js/api'

getorglist({
    
     id: 200 }).then(res => {
    
    
  console.log(res)
})

In this way, unified management can apibe achieved, and future maintenance and modification only need to api.jsbe performed on the file.

request interceptor

The request interceptor can add a token to each request, and it is easy to maintain after unified processing

// 请求拦截器
axios.interceptors.request.use(
  config => {
    
    
    // 每次发送请求之前判断是否存在token
    // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的
    token && (config.headers.Authorization = token)
    return config
  },
  error => {
    
    
    return Promise.error(error)
  })

response interceptor

The response interceptor can perform a layer of operations after receiving the response, such as judging the login status and authorization based on the status code

// 响应拦截器
axios.interceptors.response.use(response => {
    
    
  // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
  // 否则的话抛出错误
  if (response.status === 200) {
    
    
    if (response.data.code === 511) {
    
    
      // 未授权调取授权接口
    } else if (response.data.code === 510) {
    
    
      // 未登录跳转登录页
    } else {
    
    
      return Promise.resolve(response)
    }
  } else {
    
    
    return Promise.reject(response)
  }
}, error => {
    
    
  // 我们可以在这里对异常状态作统一处理
  if (error.response.status) {
    
    
    // 处理请求失败的情况
    // 对不同返回码对相应处理
    return Promise.reject(error.response)
  }
})

summary

  • Encapsulation is a very meaningful means in programming. Simple axiosencapsulation allows us to appreciate its charm
  • Encapsulation axiosThere is no absolute standard, as long as your encapsulation can meet your project requirements and is easy to use, it is a good encapsulation solution

reference article

  • https://www.html.cn/qa/vue-js/20544.html
  • https://juejin.cn/post/6844904033782611976
  • https://juejin.cn/post/6844903801451708429

Guess you like

Origin blog.csdn.net/weixin_46862327/article/details/130051431