首页 前端知识 干货分享:Vue 3和TypeScript结合进行API封装

干货分享:Vue 3和TypeScript结合进行API封装

2024-07-20 17:07:33 前端知识 前端哥 75 816 我要收藏

前言:

    在现代的前端开发中,使用Vue 3和TypeScript结合进行API封装已经成为一种流行的实践。通过将Vue 3的响应式性与TypeScript的静态类型检查相结合,我们可以更加安全和高效地管理和使用接口请求。本文将介绍如何在Vue 3项目中使用TypeScript进行API封装,以提高代码质量、可维护性和可读性。从创建API Service到定义接口类型,从封装请求方法到统一处理错误,本文将逐步引导您实现一个高度可扩展和可维护的API封装方案。让我们一起探索如何利用Vue 3和TypeScript的强大特性,优化前端项目的接口请求管理。

1.介绍

    封装API的主要原因是为了提高代码的可维护性和复用性。通过封装API,可以隐藏实现细节,使得其它模块或应用程序只需关注接口的调用方式,而无需关心具体实现。这样在以后需要修改实现时,只需要修改封装的API,而不会影响到其它代码。

    使用TypeScript的优势包括类型检查和丰富的功能。TypeScript是JavaScript的超集,添加了静态类型系统,可以在编码阶段发现很多潜在的错误。这有助于提高代码的质量和可靠性。此外,TypeScript还提供了模块化、泛型等特性,可以让代码更加清晰易读,并在开发过程中提供更好的工具支持。因此,结合封装API和使用TypeScript可以更好地编写高质量且易维护的代码。

2. 项目准备

  • 确保你的Vue项目已经配置好TypeScript支持。
  • 安装axios网络请求库并引入。
  • 安装qs

3.创建API Service类

    在src内命名一个api 的文件夹,在api文件夹内创建axios.config.ts 、http.ts 、url.ts。

4.定义接口类型

    在axios.config.ts内定义接口类型,使用TypeScript定义接口类型,包括请求参数类型和响应数据类型。

import Axios, { AxiosResponse } from 'axios'
import qs from 'qs'


//这里为后端传递来的接口地址通用前缀
export const baseURL = 'https://'

//例如: https://gmall-prod.atguigu.cn/mall-api/



export const CONTENT_TYPE = 'Content-Type'

export const FILE_CONTENT_TYPE = 'multipart/form-data' //传输文件格式数据

export const FORM_URLENCODED = 'application/x-www-form-urlencoded; charset=UTF-8'

export const APPLICATION_JSON = 'application/json; charset=UTF-8'

export const TEXT_PLAIN = 'text/plain; charset=UTF-8'

const service = Axios.create({
  timeout: 10 * 60 * 1000,
})

service.interceptors.request.use(
  (config) => {
    !config.headers && (config.headers = {})

    if (!config.headers[CONTENT_TYPE]) {
      config.headers[CONTENT_TYPE] = FILE_CONTENT_TYPE
    }

    if (config.headers[CONTENT_TYPE] === FORM_URLENCODED) {
      config.data = qs.stringify(config.data)
    }
    return config
  },
  (error) => {
    return Promise.reject(error.response)
  }
)

service.interceptors.response.use(
  (response: AxiosResponse): AxiosResponse => {
    if (response.status === 200) {
      return response
    } else {
      throw new Error(response.status.toString())
    }
  },
  (error) => {
    if (import.meta.env.MODE === 'development') {
      console.log(error)
    }
    console.log(error.response);

    return Promise.reject({ code: 500, msg: '服务器异常,请稍后重试…' })
  }
)

export default service

5. 封装请求方法 

   在http.ts内封装基本的GET、POST等请求方法,处理请求前后逻辑。

import { AxiosResponse } from 'axios'
import { App } from '@vue/runtime-core'
import request from './axios.config'

export interface HttpOption {
  url: string
  data?: any
  method?: string
  headers?: any
  beforeRequest?: () => void
  afterRequest?: () => void
}

export interface Response<T = any> {
  totalSize: number | 0
  code: number
  msg: string
  data: T
}

function http<T = any>({ url, data, method, headers, beforeRequest, afterRequest }: HttpOption) {
  const successHandler = (res: AxiosResponse<Response<T>>) => {
    if (res.status === 200) {
      return res.data
    }
    throw new Error(res.data.msg || '请求失败,未知异常')
  }
  const failHandler = (error: Response<Error>) => {
    afterRequest && afterRequest()
    throw new Error(error.msg || '请求失败,未知异常')
  }
  beforeRequest && beforeRequest()
  method = method || 'GET'
  const params = Object.assign(typeof data === 'function' ? data() : data || {}, {})
  return method === 'GET'
    ? request.get(url, params,{ headers: headers }).then(successHandler, failHandler)
    : request.post(url, params, { headers: headers }).then(successHandler, failHandler)
}

export function get<T = any>({
  url,
  data,
  method = 'GET',
  headers,
  beforeRequest,
  afterRequest,
}: HttpOption): Promise<Response<T>> {
  return http<T>({
    url,
    method,
    data,
    headers,
    beforeRequest,
    afterRequest,
  })
}

export function post<T = any>({
  url,
  data,
  method = 'POST',
  headers,
  beforeRequest,
  afterRequest,
}: HttpOption): Promise<Response<T>> {
  return http<T>({
    url,
    method,
    data,
    headers,
    beforeRequest,
    afterRequest,
  })
}

function install(app: App): void {
  app.config.globalProperties.$http = http

  app.config.globalProperties.$get = get

  app.config.globalProperties.$post = post
}

export default {
  install,
  get,
  post,
}

declare module '@vue/runtime-core' {
  // 为 `this.$` 提供类型声明
  interface ComponentCustomProperties {
    $get: <T>(options: HttpOption) => Promise<Response<T>>
    $post: <T>(options: HttpOption) => Promise<Response<T>>
  }
}

6.封装调用接口

    在url.ts中对使用的接口进行简单封装,这里简单演示一个登录的接口Login

import { baseURL } from './axios.config'

export const baseAddress1 = baseURL

//baseURL就是axios.config.ts内封装好的 https://gmall-prod.atguigu.cn/mall-api/

export const Login = baseAddress1 + 'login' // 登录接口

//Login的完整地址:https://gmall-prod.atguigu.cn/mall-api/login

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $urlPath: Record<string, string>
  }
}

7.在Vue组件中使用API Service

    在login.vue中使用上述封装api

<script setup>
import { post, get } from '../../../api/http'
import { Login } from'../../../api/url';


//调用登录接口
function toLogin(){
  post({
    url: Login, // 这里就是封装好的api地址
    data:{
      userid: 666,  //data为接口的各个参数
      key: xxx
    }
  }).then(res =>{
     //res 接口成功返回的数据
  })
}

</script>

结语: 

通过封装API和使用TypeScript,我们可以提高项目的代码质量、可维护性和可读性。封装API可以帮助我们更好地组织接口请求逻辑,降低耦合度,统一管理请求。而使用TypeScript则可以通过静态类型检查和类型推断帮助我们避免潜在的错误,提升代码的稳定性和可靠性。

希望本文能够帮助您更好地理解如何在Vue 3项目中结合API封装和TypeScript优化前端开发流程,提升团队的开发效率和项目的质量。祝您使用愉快!如果有任何问题或建议,请随时与我联系。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/14043.html
标签
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!