Vue 项目 API 接口封装2

简介: Vue 项目 API 接口封装2

六、API 接口封装

最后一步,对于 API 接口封装,我们使用面向对象的方式组织数据。

6.1 文件结构划分

在 src 目录下新建 api 目录,然后根据后端 API 接口文档划分模块:

src/api // api interface files
  |_ user // 用户模块
    |_ index.js
  |_ goods // 货物模块
    |_ index.js
  |_ carts // 购物车模块
    |_ index.js
  |_ index.js

6.2 按模块编写

货物模块为例,路径为:src/api/goods/index.js

import axios from '@/utils/request' // axios 实例引入(第五节封装的)
const goods = {
    // 1. 获取所有货物信息
    getGoods: () => axios({
      url: '/api/product1/v1/goods',
      method: 'get'
    }),
    // 2. 获取某条货物信息
    getGoodsById: (id) => axios({
      url: `/api/product1/v1/goods/${id}`,
      method: 'get'
    }),
    // 3. 新增一条货物信息
    addGoods: (data) => axios({
      url: '/api/product1/v1/goods',
      method: 'post',
      data
    }),
    // 4. 删除某条货物信息
    deleteGoodsById: (id) => axios({
      url: `/api/product1/v1/goods/${id}`,
      method: 'delete'
    }),
    // 5. 更新某条货物信息
    // put 与 patch 的区别:put 所有字段均要传递;patch 可选字段传递,不用全部传
    updateGoodsById: (id, data) => axios({
      url: `/api/product1/v1/goods/${id}`,
      method: 'put',
      data
    }),
    // 6. 下载货物报表
    downloadGoodsReport: (data) => axios({
      url: `/api/product1/v1/goods/report`,
      method: 'post',
      data,
      responseType: 'blob' // browser only: 'blob'
    }),
    // 7. 上传货物报表
    uploadGoodsReport: (data) => axios({
      url: `/api/product1/v1/goods/up_report`,
      method: 'post',
      data,
      headers:{"Content-Type": "multipart/form-data"}
    })
}
export default goods

以上,展示了常用的请求形式,包括:GET, POST, PUT/PATCH, DELETE

补充几点:

  • url = base url + request url,其中 base url 就是在 5.1 节中,axios 实例上的 baseURL: process.env.VUE_APP_BASE_URL
  • 第五条更新数据,用了 PUT,其实还有一个类似的 PATCH,他们的区别在上面已经给了注释。PUT 和 PATCH 的区别:stackoverflow.com/questions/2…
  • 发送 POST 请求使用 data ,而发送 GET 请求时,可能需要带上 url 参数,这时候就要用到 params 了。
    举个请求购物车分页数据的例子:http://xxx.yyy.zzz:3000/api/product1/v1/carts?page=1&size=-1
// src/api/carts/index.js
import axios from '@/utils/request'
const carts = {
    // ...
    // 获取购物车信息
    getCarts: (params) => axios({
        url: '/api/product1/v1/carts',
        method: 'get',
        params
    })
}
export default carts

有时候我们还会看到,在发送 POST 请求时,有人会使用 qs ,它的作用是序列化 JSON 格式数据为 urlencoded 格式的字符串。

原因是后端语言处理 JSON 格式的数据比较麻烦,例如 Go 语言的 Gin 框架,传递给它 {Country: Brasil, City: Belo Horizonte} ,为了安全起见,需要开发人员据此单独做结构体,而传递 'Country=Brasil&City=Belo Horizonte' 这样的字符串则更为合适。

这里改写一下货物模块中的第三个 POST 请求,记得首先要引入 qs 模块:

import axios from '@/utils/request'
+ import qs from 'qs' 
const goods = {
    // ...
    // 3. 新增一条货物信息
    addGoods: (data) => axios({
        url: '/api/product1/v1/goods',
        method: 'post',
        data: qs.stringify(data)
    }),
    // ...
}
export default goods
  • 关于urlencoded可以查看以下三篇参考:
  • axios-http.com/docs/urlenc…
  • stackoverflow.com/questions/4…
  • developer.mozilla.org/zh-CN/docs/…

6.3 导出 API 对象

当写完各个模块的 api 请求接口后,就需要导出了。回到第二节的构思,我们想要通过 this.$api.moduleName.methodName(…args) 的形式调用方法发起请求。

进入 src/api/index.js

import user from './user'
import goods from './goods'
import carts from './carts'
// ...
class API {
    constructor () {
        this.user = user
        this.goods = goods
        this.carts = carts
        // ...
    }
}
// 导出使用
export default new API()

6.4 小试牛刀

将 API 实例导出之后,将它挂载到 Vue 原型上,就能正常使用了。

// src/main.js
import API from './api'
Vue.prototype.$api = API
// Test.vue
<template>
    <button @click="handleData">test request</button>
</template>
<script>
export default {
    name: 'Test',
    data () {
        return {
            tableData: []
        }
    },
    methods: {
        fetchData () {
            return this.$api.goods.getGoods()
        },
        async handleData () {
            try {
                const response = await this.fetchData()
                // ...
            } catch (e) {
                console.error(e)
            }
        }
    }
}
</script>

6.5 冗余问题的解决

以上,其实还有一个问题尚未解决,就是每一个请求 api 的 url 里的 /api/product1/v1 都是重复的,这个容易,把它分离出去变成一个模块,自定义 url 前缀。

src/api/url_prefixes.js

function generatePrefix ({productName, version} = {productName: 'product1', version: 'v1'}) {
    return `/api/${productName}/${version}`
}
export const v1 = generatePrefix() // '/api/product1/v1'
export const v2 = generatePrefix({version: 'v2'}) // '/api/product1/v2'
export const p2v2 = generatePrefix({productName: 'product2', version: 'v2'}) // '/api/product2/v2'

从上面可以看到,除了接口版本可能会发生变化,产品名称也是有可能发生变化的,我们也用变量控制。之后,在各模块的 api 文件中就可以用使用变量来控制 url 前缀部分了。

例如改写货物模块的 api url 前缀:

import axios from '@/utils/request' // axios 实例引入(第五节封装的)
import { v1 } from '../**url_prefixes**.js' // 引入前缀:**'/api/product1/v1'**
const goods = {
    // 1. 获取所有货物信息
    getGoods: () => axios({
      url: `${v1}/v1/goods`,
      method: 'get'
    }),
    // 2. 获取某条货物信息
    getGoodsById: (id) => axios({
      url: `${v1}/goods/${id}`,
      method: 'get'
    }),
    // 3. 新增一条货物信息
    addGoods: (data) => axios({
      url: `${v1}/v1/goods`,
      method: 'post',
      data
    }),
    // ...
}
export default goods

至此,三个关键问题都已经得到了解决:

  • 永久性变量冗余
  • 高强度心智负担
  • 模块过于扁平化


七、总结

请求的 API 封装到此就结束了,除了以上这种面向对象的设计以外,还有其他的方式。最后,整理一下封装的整体流程:

  1. 请求 API 结构设计,this.$api.moduleName.methodName(…args)
  2. 脚手架模式与环境变量设置
  3. Axios 封装(包括实例配置和拦截器),导出实例
  4. 请求 API 编写及导出,注意分模块编写
  5. 将 API 挂载到 Vue 实例,正常使用

文章里,我添加了很多参考链接,如有疑惑可以看一看,看完如果仍然有疑惑,那就找人讨论吧,之后这一块内容你应该就可以掌握了。



目录
相关文章
|
17天前
|
缓存 测试技术 API
API的封装步骤流程
API封装流程是一个系统化的过程,旨在将内部功能转化为可复用的接口供外部调用。流程包括明确需求、设计接口、选择技术和工具、编写代码、测试、文档编写及部署维护。具体步骤为确定业务功能、数据来源;设计URL、请求方式、参数及响应格式;选择开发语言、框架和数据库技术;实现数据连接、业务逻辑、错误处理;进行功能、性能测试;编写详细文档;部署并持续维护。通过这些步骤,确保API稳定可靠,提高性能。
|
26天前
|
前端开发
vue3+ts项目中使用mockjs
vue3+ts项目中使用mockjs
247 58
|
8天前
|
API PHP
ThinkPHP 通用的API格式封装
本文介绍了在ThinkPHP框架中如何统一封装API返回格式的方法,包括创建状态码枚举类、编写统一格式化函数以及在BaseController和Error控制器中重写`__call`方法来处理不存在的方法或控制器调用,以实现统一的错误处理和返回格式。
ThinkPHP 通用的API格式封装
|
8天前
|
JavaScript
vue项目中使用vue-router进行路由配置及嵌套多级路由
该文章详细说明了如何在Vue项目中配置和使用vue-router进行单页面应用的路由管理,包括设置嵌套路由和实现多级路由导航的示例。
vue项目中使用vue-router进行路由配置及嵌套多级路由
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
14 4
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【51.路由懒加载】
vue尚品汇商城项目-day07【51.路由懒加载】
15 4
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
14 2
|
6天前
|
API UED
如何实现Vue2项目升级Vue3?
如何实现Vue2项目升级Vue3?
14 1
|
8天前
|
JavaScript
vue项目中引入阿里图标iconfont
该文章指导如何在Vue项目中引入并使用阿里图标库Iconfont,包括图标的选取、下载配置文件及在项目中引入和使用图标的具体步骤。
|
13天前
|
JSON 资源调度 JavaScript
Vue框架中Ajax请求的实现方式:使用axios库或fetch API
选择 `axios`还是 `fetch`取决于项目需求和个人偏好。`axios`提供了更丰富的API和更灵活的错误处理方式,适用于需要复杂请求配置的场景。而 `fetch`作为现代浏览器的原生API,使用起来更为简洁,但在旧浏览器兼容性和某些高级特性上可能略显不足。无论选择哪种方式,它们都能有效地在Vue应用中实现Ajax请求的功能。
18 4