Vue 项目 API 接口封装1

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

一、前言

之前接手了实习生写的项目,我对很多地方做了完善,其中包括 API 接口封装,因此借此机会将这部分经验转化为文字分享给大家。看前须知,项目是用 VueCLI 搭建的。

一般来说,公司的后端采用 RESTful API 的规范来编写接口的。

项目前期接口较少,因此前后端联调时,请求数据时一般会写成这样:

// 拿取货物数据
fetchGoodsData () {
  return axios.get('http://xxx.yyy.zzz:3000/api/product1/v1/goods')
}

然而,随着产品的功能迭代,接口自然也会越来越多,如果还是按照上面的方式去写,将会面临一系列的麻烦:

第一、永久性变量冗余。 例如, http://xxx.yyy.zzz:3000/api/product1/v1/ ,这一串几乎永远是冗余的;

第二、高强度心智负担。 例如,http://xxx.yyy.zzz:3000/api/product1/v1/carts?page=1&size=-1 ,一旦传递的参数过多,就会出现漏写、写错的情况;

第三、模块过于扁平化。 我们从上面几个接口上是无法直接判断当前接口请求的数据究竟属于哪一个功能模块,而且请求含义不明确,非常依赖开发人员编写的方法名。

为了解决以上几个难题,我们就需要对 API 进行封装。


二、问题分析

面对这样一个复杂的问题,思路往往是反其道而行之的,“分而治之”, 让其简单化。

打开后端给的 API 文档,举个例子,假设有以下几个模块:

  • 用户模块
  • 货物模块
  • 购物车模块
  • ……

回想前言中提到的第三个问题——模块过于扁平化,无法区分接口属于哪个功能模块,无法区分请求含义。

如何让我们在发请求时更清晰地分辨接口呢?

// 拿取货物数据
fetchGoodsData () {
  return this.$api.goods.fetchGoodsData()
}


3.jpg


如上图,只是观察函数调用即可明确功能模块、请求的具体含义。

与此同时还解决了第一个问题——永久性冗余,冗余的信息被封装到了 axios 实例中。

对于第二个问题——请求参数过多,认知负担增加,我们把需要传递的数据传进去即可,像这样:

// 拿取货物数据
fetchCartsData (params) {
  return this.$api.carts.fetchCartsData(params)
}
// 获取所有购物车数据,不分页
fetchCartsData({
    pages: 1,
    size: -1
})
.then(data => {
    // ...
})
.catch(e => console.error(e))

看到这里,如果你是一位新手,应该会一头雾水,那就对了。因为也许你并不知道http://xxx.yyy.zzz:3000/api/product1/v1/ 去哪了,也不知道 ?page=1&size=-1 怎么就突然作为参数传到封装好的 API 函数里去了。

Take it easy,just go on.


三、Axios

我们简单过一下 Axios —— 基于 Promise 的 HTTP 客户端,可用于浏览器和 node.js,还可以拦截请求和响应,转化请求和响应数据,取消请求,自动转换 JSON 数据,防御 XSRF 攻击……

简而言之,它可以帮你获取数据,请求和响应时帮你拦截数据,总是返回一个 Promise,然后你从 Promise 里拿到数据,整理后展示到页面上。


2.jpg


回到第二节末尾提出的问题: http://xxx.yyy.zzz:3000/api/product1/v1/ 去哪了??page=1&size=-1 去哪了?它们都被放进了 axios 实例中。具体来说,前者被放到了 baseURL 中,后者以对象的形式被放到了 params 中。参考链接:axios-http.com/docs/req_co…

如下图,一个 axios 实例主要由两个部分组成:拦截器、配置。


1.jpg


在正常的开发中,前端可能需要连接不同环境进行接口联调,因此其中,http://xxx.yyy.zzz:3000/api/product1/v1/ 作为 baseURL 就不能写死,需要根据本地服务器的模式来进行转换。

打个比方,如果是开发环境,baseURL 切换为 http://192.168.1.1:30000;如果是测试环境,baseURL 切换为 http://192.168.1.3:40000。因此,我们只要将 baseURL 的地址写在环境变量中就可以了。

现在我们需要设置模式及其环境变量,之后通过 process.env 就可以获取到对应变量。


四、模式与环境变量

VueCLI 提供了几种默认的模式,但是一般我们都会自己自定义。

通过 --mode 可以定义模式,例如,我要定义测试模式(其他模式以此类推)。

打开 package.json,找到 scripts 这一项,添加测试模式:

"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "test": "vue-cli-service serve --mode test"
}

另外,我们需要在根目录下(和 src 目录同级)新建一个 .env.test 文件,用来保存环境变量:

NODE_ENV = 'test'
VUE_APP_BASE_URL = 'http://192.168.1.3:4000'

之后,来到 main.js 中,添加一条 console.log(process.env);

打开控制台,执行命令:npm run test

项目运行后,在浏览器的控制台中就能看到 process.env 里保存着 NODE_ENV 和 VUE_APP_BASE_URL。


.jpg


有了这两个变量,模式和环境变量就有了对应关系。然后将 process.env.VUE_APP_BASE_URL 赋值给 axios 实例的 baseURL,就能实现 baseURL 的灵活转换。

补充几点:

  • mode 的参数与 .env 文件后缀有关系。
.env                # 在所有的环境中被载入
.env.local          # 在所有的环境中被载入,但会被 git 忽略
.env.[mode]         # 只在指定的模式中被载入
.env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略
  • VUE_APP_* 是 VueCLI 通过 webpack.DefinePlugin 静态地嵌入到客户端侧 的代码中的。
  • 更多的疑惑,参考这篇文章:cli.vuejs.org/zh/guide/mo…

五、Axios 封装

Axios 的封装需要管理两件事情:一是创建实例,二是设置拦截器。

找到 utils 目录,在里面新建 request.js

5.1 创建实例

  • axios-http.com/docs/instan…
import axios from 'axios'
// create an axios instance: <https://axios-http.com/docs/instance>
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL,
    timeout: 10 * 1000
})
export default service

可以看到这里的 baseURL 用的是就是对应模式下的环境变量了。

5.2 请求拦截器 & 响应拦截器

  • axios-http.com/docs/interc…
// ...
// request interceptor: <https://axios-http.com/docs/interceptors>
service.interceptors.request.use(
    config => {
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
service.interceptors.response.use(
    response => {
        return response
    },
    error => {
        return Promise.reject(error)
    }
)
// ...

到此,axios 实例就准备完毕了,有 baseURL,有拦截器。

axios 的封装与本文主题无关,所以写得很简单。但是这里也给大家提供一篇参考。这是另外一种思维方式,也值得学习:developpaper.com/encapsulati…

目录
相关文章
|
2月前
vue3+Ts 二次封装ElementUI form表单
【10月更文挑战第8天】
202 59
|
3月前
|
资源调度 JavaScript API
vue3封装城市联动组件
vue3封装城市联动组件
236 63
|
2月前
|
JavaScript API
vue中api统一管理
【10月更文挑战第4天】
|
3月前
|
缓存 测试技术 API
API的封装步骤流程
API封装流程是一个系统化的过程,旨在将内部功能转化为可复用的接口供外部调用。流程包括明确需求、设计接口、选择技术和工具、编写代码、测试、文档编写及部署维护。具体步骤为确定业务功能、数据来源;设计URL、请求方式、参数及响应格式;选择开发语言、框架和数据库技术;实现数据连接、业务逻辑、错误处理;进行功能、性能测试;编写详细文档;部署并持续维护。通过这些步骤,确保API稳定可靠,提高性能。
|
2月前
|
Web App开发 JavaScript 数据可视化
vue3扩展echart封装为组件库-快速复用
vue3扩展echart封装为组件库-快速复用
152 7
|
3月前
|
API PHP
ThinkPHP 通用的API格式封装
本文介绍了在ThinkPHP框架中如何统一封装API返回格式的方法,包括创建状态码枚举类、编写统一格式化函数以及在BaseController和Error控制器中重写`__call`方法来处理不存在的方法或控制器调用,以实现统一的错误处理和返回格式。
ThinkPHP 通用的API格式封装
|
2月前
|
JavaScript 前端开发 API
探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
【10月更文挑战第5天】探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
|
3月前
|
JavaScript
Vue2.0、Vue3.0分别使用v-model封装组件[Vue必会]
本文介绍了在Vue 2和Vue 3中如何使用`v-model`来实现组件间的双向数据绑定,包括在Vue 2中使用`value`和`input`事件,以及在Vue 3中使用`modelValue`和`update:modelValue`事件的方法。
272 22
|
2月前
|
JSON JavaScript API
(API接口系列)商品详情数据封装接口json数据格式分析
在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
2月前
|
前端开发 JavaScript API
惊呆了!学会AJAX与Fetch API,你的Python Web项目瞬间高大上!
在Web开发领域,AJAX与Fetch API是提升交互体验的关键技术。AJAX(Asynchronous JavaScript and XML)作为异步通信的先驱,通过XMLHttpRequest对象实现了局部页面更新,提升了应用流畅度。Fetch API则以更现代、简洁的方式处理HTTP请求,基于Promises提供了丰富的功能。当与Python Web框架(如Django、Flask)结合时,这两者能显著增强应用的响应速度和用户体验,使项目更加高效、高大上。
51 2