接口封装

使用场景

当我们在Vue项目开发当中,经常会去调用后端的接口,所以我们在Vue搭建的过程中,需要对接口请求进行封装

在封装的过程中我们需要去安装 axios 这个插件,来帮助我们发送http请求

下面就是封装的过程

安装axios

yarn add axios -S

请求服务封装

src/services/request.js

//引入axios异步请求插件
import axios from 'axios'

let cancel ,promiseArr = {}

const CancelToken = axios.CancelToken;

//请求拦截器
axios.interceptors.request.use(config => {
    //发起请求时,取消掉当前正在进行的相同请求
    if (promiseArr[config.url]) {
        promiseArr[config.url]('操作取消')
        promiseArr[config.url] = cancel
    } else {
        promiseArr[config.url] = cancel
    }
      return config
}, error => {
    return Promise.reject(error)
})

//响应拦截器即异常处理
axios.interceptors.response.use(
  response => {
      // return response
      return response.data
  }, 
  err => {
      if (err && err.response) {
        switch (err.response.status) {
          case 400:
            err.message = '错误请求'
            break;
          case 401:
            err.message = '未授权,请重新登录'
            break;
          case 403:
            err.message = '拒绝访问'
            break;
          case 404:
            err.message = '请求错误,未找到该资源'
            break;
          case 405:
            err.message = '请求方法未允许'
            break;
          case 408:
            err.message = '请求超时'
            break;
          case 500:
            err.message = '服务器端出错'
            break;
          case 501:
            err.message = '网络未实现'
            break;
          case 502:
            err.message = '网络错误'
            break;
          case 503:
            err.message = '服务不可用'
            break;
          case 504:
            err.message = '网络超时'
            break;
          case 505:
            err.message = 'http版本不支持该请求'
            break;
          default:
            err.message = `连接错误${err.response.status}`
        }
      } else {
        err.message = "连接到服务器失败"
      }
      console.err(err.message)
        return Promise.resolve(err.response)
  }
)

//请求的默认前缀 只要是发出去请求就会 默认带上这个前缀
axios.defaults.baseURL = '/api'

//设置默认请求头 异步的
axios.defaults.headers = {
    'X-Requested-With': 'XMLHttpRequest'
}

//设置超时请求时间
axios.defaults.timeout = 10000


//get请求
let GET = (data = {}) => {
  return new Promise((resolve,reject) => {
    axios({
      method: 'get',
      url:data.url,
      params: data.params,
      cancelToken: new CancelToken(c => {
        cancel = c
      })
    }).then(res => {
      resolve(res)
    })
  })
}

//post请求
let POST = (data = {}) =>
{
  return new Promise((resolve,reject) => {
    axios({
      method: 'post',
      url:data.url,
      data:data.params,
      cancelToken: new CancelToken(c => {
        cancel = c
      })
    }).then(res => {
      resolve(res)
    })
  })
}

// 文件上传请求
let UPLOAD = (data = {}) =>
{
  //封装表单数据对象
  var RequestData = new FormData()

  if(JSON.stringify(data.params) != "{}")
  {
    for(var key in data.params)
    {
      RequestData.append(key, data.params[key])
    }
  }

  return new Promise((resolve,reject) => {
    axios({
      method: 'post',
      url:data.url,
      data:RequestData,
      headers:{'Content-Type': 'multipart/form-data'},
      cancelToken: new CancelToken(c => {
        cancel = c
      })
    }).then(res => {
      resolve(res)
    })
  })
}


export {
  GET,
  POST,
  UPLOAD
}

接口的目录结构

services/              存放自定义封装的服务文件
    request.js         axios二次封装的请求服务库


api/
    user/
        address.js
        base.js
        index.js

    product/
        product.js
        index.js

    index.js

由此可见我们发现每个目录下面都有一个index.js这个文件,那么这个文件就是每个接口的入口文件

总入口文件

src/api/index.js

// 引入每个目录下面的index.js文件
const ModulesFile = import.meta.globEager("./*/index.js")

//接口集合
var ApiList = {}

//提取对象下的值 同步
Object.values(ModulesFile).map(async mod => {
    if(mod.default)
    {
      //合并对象 循环多次合并
      ApiList = Object.assign(ApiList, mod.default)
    }
})

//让vue应用(app)继承接口服务  当使用.use挂载的时候, install函数就会被执行
ApiList.install = (app) => {
    //定义全局
    app.config.globalProperties.$api = ApiList
}

//导出接口集合
export default ApiList

每个独立接口模块下面的index.js

src/api/user/index.js

//引入当前目录下面所有的文件
const ModulesFile = import.meta.globEager('./*.js')

//接口列表
var ApiList = {}

Object.values(ModulesFile).map(async mod => {
    if(mod.default)
    {
        //合并对象 循环多次合并
        ApiList = Object.assign(ApiList,mod.default)
    }
})

export default ApiList

其他的接口文件

src/api/user/base.js

//引入封装的公共的请求插件
import {GET, POST, UPLOAD} from '@/services/request.js'

export default {
    register(data = {})
    {
        //注册接口
        //api/user/base/register
        return POST({
            url:'/user/base/register',
            params:data
        })
    },
    login(data = {})
    {
        //登录接口
        return POST({
            url:'/user/base/login',
            params:data
        })
    },
    profile(data = {}) 
    {
        //更改用户资料接口
        return UPLOAD({
            url:'/user/base/profile',
            params:data
        })
    }
}

全局挂载

src/main.js

//加载接口
import api from './api/index.js'

//挂载
const app = createApp(App)
    .use(api)
    .mount('#app')

在业务中使用

src/components/home.vue

export default {
    async created()
    {
      //接口请求
      var result = await this.$api.ProductIndex()
      console.log(result)
    }
}
powered by GitbookEdit Time: 2023-04-08 10:28:32