# axios

axios 文档地址:http://www.axios-js.com (opens new window)

# 项目中的封装

axios 的封装方式网上多如牛毛,可以根据自己的业务进行适合的封装,以提高代码复用率与维护便捷度。

以下是本项目对 axios 的封装

import axios from 'axios'
import store from '@/store'
import router from '@/router/index'
import { API_DOMAIN } from '@/config'
import { Message } from 'element-ui'    // 引入提示组件

// axios 配置
axios.defaults.timeout = 60000          // 接口超时时长 60s
axios.defaults.baseURL = API_DOMAIN     // 接口域名
axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8'


// 请求时的拦截
axios.interceptors.request.use(config => {
    // 登录成功后 token 信息会存入到 localStorage 和 vuex 中
    // 如果 store 中存在 token,则请求时携带上
    // 如果后端接口不需要传入 token,后端接口会直接忽略
    if (store.state.user.token) {
        config.headers['Authorization'] = 'Bearer ' + store.state.user.token
    }
    return config
}, function (error) {
    return Promise.reject(error)
})

// 返回值
axios.interceptors.response.use(res => {
    if (res.status === 200) {
        if (['post', 'patch', 'put', 'delete'].includes(method)) {
            // 非登录接口
            if (!res.config.url.includes('login')) {
                Message({
                    message: res.data.message,
                    type: 'success'
                })
            }
        } else if (method === 'get') {
            // 对 created_at 截取
            if (Array.isArray(res.data.data)) {
                res.data.data.map(item => {
                    if (item.created_at) {
                        item.created_at = item.created_at.slice(0, 10)
                    }
                })
            }
        }
        return res.data
    }

    // 此处接口只要有返回,无论是什么错误,都重新整理为以下通用格式
    return {
		code: res.status_code,
		message: res.message,
		data: {}
	}

}, error => {

    if (String(error).includes('timeout')) {
		Message.error('网络请求超时')
	} else if (String(error).includes('Network Error')) {
		Message.error('网络异常')
	} else if (error.response) {
		const { status, data } = error.response
		if (status === 401) {
			Message.error('请重新登录')
			localStorage.clear()            // 清空 storage 存储数据
			router.replace('/login')        // 跳转到登录页
		} else {
			Message.error(status + ' ' + data.message)
		}
	}

    // 后端无返回时,组装一个返回错误的数据,不然 await 后的代码无法运行,
    // 导致后面的 this.loading 等方法无法执行,页面停留在加载状态
    // 也可以给每个请求包裹 try catch 处理,但是会麻烦
    return {
        'code': 400,
        'messsage': 'error'
    }
})

// 导出请求方法
export default {
  get(url, params) {
    return axios({
      method: 'get',
      url,
      params
    })
  },

  post(url, data) {
    return axios({
      method: 'post',
      url,
      data
    })
  },

  patch(url, data) {
    return axios({
      method: 'patch',
      url,
      data
    })
  },

  put(url, data) {
    return axios({
      method: 'put',
      url,
      data
    })
  },

  delete(url, data) {
    return axios({
      method: 'delete',
      url,
      data
    })
  }
}

# 接口定义

// 导入封装的 axios 文件并命名为 http
import http from '@/http/index'

// 定义一个获取影视评论的接口
export const getMovieComments = (id, params) => http.get(`/movies/${id}/comments`, params);

# 接口使用

import { getMovieComments } from "@/api/movie";

...

data() {
    return {
        loading: false,
        list: [],
        pagination: {},
    }
},

mounted() {
    this.getMovieComments();
},

methods: {
    async getMovieComments() {
        this.loading = true;
        
        let params = {
            page: this.page
        }
        let {code, data, total } = await getMovieComments(id, params);

        if(code === 200) {
            this.list = res.data;
            this.pagination.total = res.total;
        }

        this.$nextTick(() => {
            this.loading = false;
        })
    }
}

上次更新: 6/21/2022, 6:25:22 PM