vue-cli3+ 搭建pc端管理项目(五, axios 使用及封装)

任何一个系统,和后端的数据交互都是必要的。vue 项目推荐使用 axios

安装

npm install axios

使用

第一种方式,将 axios 添加到 Vue 原型上。(不推荐)

// main.js
import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import axios from 'axios'

import './plugins/element'
import './assets/scss/main.scss'

Vue.config.productionTip = false
Vue.prototype.$axios = axios

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
// user.vue

queryInfo () {
  this.$axios.get('url').then(res => {
    console.log(res)
  }).catch(err => {
    console.log(err)
  })
}

在实际的项目开发中,不推荐这种使用方式。主要原因是这种书写方式,请求地址与业务逻辑写在一起,不利于代码维护。如果一个接口多个地方使用,一旦接口地址或者传参有变化,需要修改多个地方。我平时喜欢将接口地址放到统一的地方管理并维护。

第二种方式,对 axios 进行简易封装(推荐)

1. axios引入并添加拦截器

在 src 文件夹下新建 api 文件夹,用于存放所有的接口文件。

在 api 文件夹下新建 index.js,引入 axios ,并添加拦截器

// index.js

import axios from 'axios'
import router from '@/router/index'
import { Message } from 'element-ui'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_URL, // url = base url + request url
  timeout: 60000 * 10 // request timeout
})

// 添加请求拦截器,在请求头中加token
service.interceptors.request.use(
  config => {
    if (localStorage.getItem('token')) {
      config.headers.token = localStorage.getItem('token')
    }
    return config
  },
  error => {
    return Promise.reject(error)
  })

// 添加响应拦截器,对返回结果做统一处理
service.interceptors.response.use(function (response) {
  const status = response.data.success
  if (status === undefined) { // 下载接口返回文件流
    return response
  } else if (status) {
    return response.data.data
  } else {
    const errorCode = response.data.errorCode
    const messages = response.data.message
    // token过期
    if (errorCode === 401) {
      Message.warning('您的登录状态已过期,请重新登录')
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
      router.push({ path: '/login' })
      return Promise.reject(response.data)
    }
    if (messages) {
      Message.error(messages)
      return Promise.reject(response.data)
    } else {
      Message.error('操作失败')
      return Promise.reject(response.data)
    }
  }
}, function (error) {
  // Do something with response error
  Message.error('服务器异常')
  return Promise.reject(error)
})

export default service

axios 的拦截器有两种,请求拦截器和响应拦截器。

通常我们会在请求拦截器中,给每一个请求的 header 加上 token ,便于鉴权。

在响应拦截器中,对返回的数据做统一的处理。我们公司,前端与后端的约定是,response 的 data 中, success 为 true 则请求成功,否则请求失败,失败时,会返回 errorCode 和 message。但是对于一些下载的接口,data 则直接返回文件流。所以我的响应拦截器中分了三种情况。大家在开发中,可根据项目的情况,对拦截器加以修改。

2. 对常用的请求方式进行封装

在 api 文件夹下新建 service.js,对常用的请求方式进行简易的封装

// service.js

import service from './index'

export const baseService = function (url, data = {}, method = 'GET', header = {}, responseType = 'json') {
  // 校验 URL 必需
  if (!url) {
    console.log('请传入 request 地址')
    return
  }
  // 请求方式转为大写
  method = method.toLocaleUpperCase()

  const config = {
    url: url,
    method: method,
    headers: header,
    responseType: responseType // 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  }
  if (method === 'GET' || method === 'DELETE') {
    config.params = data
  }
  if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
    config.data = data
  }
  return service(config)
    .then(response => {
      return response
    }).catch(err => {
      return Promise.reject(err)
    })
}

export const getService = function (url, data, header, responseType) {
  return baseService(url, data, 'GET', header, responseType)
}
export const deleteService = function (url, data, header, responseType) {
  return baseService(url, data, 'DELETE', header, responseType)
}
export const postService = function (url, data, header, responseType) {
  return baseService(url, data, 'POST', header, responseType)
}
export const putService = function (url, data, header, responseType) {
  return baseService(url, data, 'PUT', header, responseType)
}

这里只对 get,post,put,delete 这四种常见的请求方式进行了封装。

这里需要注意两点:

  • get 和 post 的传参方式不一样,delete 同 get ,put 同 post
  • responseType 这个参数是必要的,对于上传下载的接口,数据为文件流,responseType 需设置为arraybuffer

3. 使用

建议大家根据模块创建对应的 js 文件,每个 js 文件,维护自己模块下的接口。

例如,login.js 用来维护登录相关的接口。

// login.js

import { getService, postService } from './service'
/**
 * name 登录
 * time 2021-09-07
 * param userName String 账号
 * param password String 密码
 * return String token
 * */
export const signIn = params => {
  return postService('/anon/login', params)
}
/**
 * name 登出
 * time 2021-09-07
 * */
export const signOut = params => {
  return getService('/auth/logout', params)
}
// login.vue

import { signIn } from '@/api/login'
export default {
  name: 'login',
  data () {
    return {
      userInfo: {}
    }
  },
  methods: {
    login () {
      const params = this.userInfo
      signIn(params).then(res => {
        console.log(res)
      })
    }
  }
}

以上,就是我在项目中使用 axios 的解决方案。

项目地址:

github地址

gitee地址

系列文章:

vue-cli3+ 搭建pc端管理项目(一, 项目创建)

vue-cli3+ 搭建pc端管理项目(二, 不同环境配置[开发,测试,生产])

vue-cli3+ 搭建pc端管理项目(三, css预处理器scss使用)

vue-cli3+ 搭建pc端管理项目(四, 按需引入 element-ui,支持修改主题色)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值