在网络开发中,封装一个简洁、高效的网络请求模块对于项目的可维护性和扩展性至关重要。本文将详细介绍如何在NuxtJS中封装一个通用的网络请求模块,并结合最佳实践来说明如何使用它来进行网络请求。

良好的代码结构和封装,不但结构清晰还能够大幅提高开发效率。下面以实战为例,以获取用户排行榜页面的完整实现为实战背景,详细介绍下NuxtJS中网络请求的封装与最佳实战。

如下图所示,右侧为用户排行榜的实现效果展示。本文详细展示网络请求的模块化封装和在具体页面上的网络接口使用。

在这里插入图片描述

封装网络请求模块

首先,引入所需的库和工具函数。使用getTokendelToken来处理用户的认证令牌。封装一个网络请求的工具方法。

//hooks/userToken.ts
import { useCookie } from '#app'// 获取 Token
export const getToken = () => {const Token = useCookie('hw_token')return Token.value
}// 设置 Token
export const setToken = (val: string) => {const Token = useCookie('hw_token')Token.value = val
}// 清空 Token
export const delToken = () => {const Token = useCookie('hw_token')Token.value = null
}

工具类封装:

// utils/request.ts
import { getToken, delToken } from '@/hooks/useToken'
// import { getUuid } from '@/hooks/useUuid'type CommonObject = Record<string, unknown>// 封装请求
// 指定后端返回的基本数据类型
export interface ResponseConfig {code: numberdata: CommonObjectmessage: string
}const CodeConfig = {/*** 接口错误信息*/// code failCodeFail: 1,// code successCodeSuc: 0,// request param errorCodeParamError: 1001,// account is existCodePhoneExist: 1002,// server internal errorCodeServerError: 1003,// token expiredCodeTokenExpired: 1004,// user not existCodeUserNotExist: 1005,// password errorCodePasswordError: 1006,// article not existCodeArticleNotExist: 2000
}// 参数排序
function sortKey(s1, s2) {if (s1 < s2) {return -1}if (s1 > s2) {return 1}return 0
}
// 参数排序
function getSortObj(originData) {const originKeys = Object.keys(originData)const sortKeys = originKeys.sort(sortKey)const sortObj = sortKeys.reduce((p, n) => {return { ...p, [n]: originData[n] }}, {})return sortObj
}const defaultOption = {// key: () => Math.random(),// lazy: true,// baseURL: process.env.BASE_URL,headers: {Authorization: '',token: '',// ts: (+new Date() / 1000) | 0,// sign: '',// 'Content-Type': 'application/x-www-form-urlencoded',// deviceType: 'pc'}
}const fetch = (url: string, options?: CommonObject): Promise<ResponseConfig> => {const { $router, $config } = useNuxtApp()const reqUrl = $config.public.BASE_URL + urlconst p: CommonObject = {...defaultOption,...options}// 加密参数const originData = options?.body || options?.params || {}const sortData = getSortObj(originData)let paramsData = JSON.stringify(sortData)if (p.method === 'get') {Object.assign(p, { params: sortData })} else {const qsData = JSON.stringify(sortData)Object.assign(p, { body: qsData })paramsData = qsData}
//   const encryStr = CryptoJS.MD5(decodeURIComponent(paramsData)).toString()const Token = getToken()Object.assign(p.headers as object, {Authorization: Token ? `Bearer ${Token}` : '',token: Token || '',// ts: (+new Date() / 1000) | 0,// sign: encryStr,// uuid: getUuid()})return new Promise((resolve, reject) => {$fetch(reqUrl, p).then((res) => {const code = (res as ResponseConfig).code || 0if (code === CodeConfig.CodeSuc) {// 成功resolve(res as ResponseConfig)return}if (code === CodeConfig.CodeTokenExpired) {// token过期delToken()$router.replace({ path: '/' })reject(res)return}if (code !== CodeConfig.CodeSuc) {reject(res)return}}).catch((err) => {reject(err)})})
}export default {get<T = ResponseConfig>(url: string, params?: CommonObject): Promise<T> {return fetch(url, { method: 'get', params }) as Promise<T>},post<T = ResponseConfig>(url: string, body?: CommonObject): Promise<T> {return fetch(url, { method: 'post', body }) as Promise<T>},put<T = ResponseConfig>(url: string, body?: CommonObject): Promise<T> {return fetch(url, { method: 'put', body }) as Promise<T>},delete<T = ResponseConfig>(url: string, body?: CommonObject): Promise<T> {return fetch(url, { method: 'delete', body }) as Promise<T>}
}
网络请求组件的介绍

在这个封装中,定义了四个主要的请求方法:getpostputdelete。这些方法分别对应于HTTP协议中的GET、POST、PUT和DELETE操作。

  • get: 用于获取数据,通常是在URL后面添加查询参数。
  • post: 用于提交数据到服务器,通常用于创建新资源。
  • put: 用于更新服务器上的数据,通常用于更新现有资源。
  • delete: 用于删除服务器上的数据,通常用于删除资源。
结合TypeScript的最佳实践

为了更好地组织代码和利用TypeScript的类型系统,建议将网络请求和响应的结构体定义单独放在一个文件中,比如types.ts,然后在API文件夹中定义具体的网络请求接口。

以获取用户排行榜接口为例:

定义请求和响应类型
// types.ts
// 定义通用对象类型
type CommonObject = Record<string, unknown>;// 定义获取用户榜单的请求和响应类型
// 定义接口参数类型
interface GetUserRankingParams extends CommonObject {limit?: number;types?: number;
}// 定义单个用户的排行榜数据类型
interface UserRanking {userName: string;nickname: string;avatarName: string;registDate: string;avatarUrl: string;articleCount: number;totalViews: number;totalComments: number;lastPostTime: string;score: number;
}// 定义响应数据类型
interface UserRankingResponse {code: number;msg: string;data: UserRanking[];
}
定义API接口

使用上述定义的类型,可以更清晰地定义API接口。将这些接口放在一个单独的文件中,比如api/index.ts

// api/index.ts
import request from '@/utils/request'
import { GetUserRankingParams, UserRankingResponse } from '@/types'/*** 获取用户排行榜API接口定义*/
export const getUserRank = (params?: GetUserRankingParams): Promise<UserRankingResponse> => {return request.get('/userRank', params)
}
使用封装后的API

在NuxtJS的组件或者其他文件中,可以这样使用封装后的API接口:

<script setup lang="ts">
import { getUserRank } from '@/api/index'
import { UserRankingResponse } from '@/types'// 使用GET请求获取数据
const fetchData = async () => {try {const response: UserRankingResponse = await getUserRank({ limit: 10, types: 1 })console.log(response.data)} catch (error) {console.error(error)}
}// 调用相应的方法
fetchData()
</script>

在VUE页面的详细使用

<template><div class="footer"><div><div class="qrcode-scan"><img src="@/assets/img/hw_qrcode.jpg" class="qrcode-img"><div class="qrcode-text"><h2 class="qrcode-title">关注坚果派公众号</h2><p class="qrcode-des">鸿蒙专属的技术社区</p></div></div><div class="sider-box"><h5 class="common-title">作者榜</h5><div class="content-box"><div><div v-for="user in rankList" :key="user.userName" class="author-item"><img :src="user.avatarUrl+user.avatarName" :alt="user.nickname" width="34" height="34" class="avatar"><NuxtLink :to="`/user/${user.userName}`" class="author-info" target="_blank" rel="noopener noreferrer"><span class="name single-ellipsis">{{ user.nickname }}</span><span class="count single-ellipsis">{{ user.articleCount }}篇文章</span></NuxtLink><a-button class="follow-btn"><span class="normal">关注</span><span class="cancel">取消关注</span></a-button></div></div></div></div></div></div>
</template><script lang="ts" setup>import { getCourselist ,getUserRank} from '~/api'const rankList = ref<UserRanking[]>([]);const fetchUserRanking = async () => {try {const params: GetUserRankingParams = {limit: 7,type: 0};const result: UserRankingResponse = await getUserRank(params);//console.log('User ranking response:', result);if (result.code === 0) {rankList.value = result.data;} else {console.error('用户排行榜请求失败,代码:', result.code, '消息:', result.msg);}} catch (error: any) {console.error('获取用户排行榜时发生错误:');if (error instanceof Error) {console.error('错误信息:', error.message);} else {console.error('未知错误:', error);}}
};fetchUserRanking()
</script>
结语

通过上述封装和最佳实践,在NuxtJS项目中可以更方便地进行网络请求,并且能够集中处理一些通用的逻辑,比如错误处理和认证信息的传递。将网络请求和响应类型定义集中放在一个文件中,不仅使得我们的代码更加整洁,还提高了代码的可维护性和可读性。这样的封装方式使得我们的项目结构更加清晰,并且易于扩展和维护。希望这篇文章能够帮助你在NuxtJS项目中实现高效的网络请求管理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90295.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90295.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90295.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云归子批量混剪软件批量剪辑软件批量分割视频更新记录

www.yunguizi.com 优化显卡硬件加速配置 ⚡ 优化 2025年07月07日 版本 v1.1.6 优化显卡硬件加速配置 修复了一些重要内容 &#x1f41b; 修复 2025年07月06日 版本 v1.1.6 修复了一些重要内容 重构读写机制 ⚡ 优化 2025年07月06日 版本 v1.1.6 优化了一些重要内容&#xff1b;…

SpringBoot校园外卖服务系统设计与实现源码

概述 基于SpringBoot开发的校园外卖服务系统&#xff0c;实现了从外卖管理到订单处理的全流程数字化解决方案&#xff0c;包含外卖管理、订单处理、用户管理等全方位功能。 主要内容 核心功能模块&#xff1a; ​​个人信息管理​​&#xff1a; 修改密码个人信息修改 ​​…

东软8位MCU低功耗调试总结

简介主控选用8位ES7P7021&#xff0c;应用于磁吸无线充电场景&#xff0c;有一个双向C口&#xff08;IP5219&#xff09;&#xff0c;MCU控制电量灯显示&#xff0c;通过IIC控制C口的降额&#xff0c;插入TYPE-C线之后有一个外部中断信号&#xff0c;触发MCU唤醒&#xff0c;开…

什么是 3D 文件?

3D 文件是 3D 对象的数字表示形式&#xff0c;可以在计算机辅助设计 &#xff08;CAD&#xff09; 软件中创建或编辑。它们包含有关物体的形状、大小和结构的信息&#xff0c;对 3D 打印过程至关重要。3D 文件格式允许在不同的程序和打印机之间交换 3D 模型&#xff0c;并确定模…

语言模型 RLHF 实践指南(一):策略网络、价值网络与 PPO 损失函数

在使用 Proximal Policy Optimization&#xff08;PPO&#xff09;对语言模型进行强化学习微调&#xff08;如 RLHF&#xff09;时&#xff0c;大家经常会问&#xff1a; 策略网络的动作概率是怎么来的&#xff1f;价值网络的得分是如何计算的&#xff1f;奖励从哪里来&#xf…

日常--记一次gitlab Runner配置与CI/CD环境搭建流程

文章目录一、前言二、相关知识1.相关定义1.什么是 CI&#xff1f;2.什么是 CD&#xff1f;2.CI/CD 构建块与工具链3.为什么要使用 CI/CD&#xff1f;三、准备四、实现1.Runner安装与配置1.更新源2.安装Runner3.注册Runner4.启动Runner5.查看Runner信息2.CI/CD流程测试1.CI/CD构…

东方仙盟AI数据中间件使用教程:开启数据交互与自动化应用新时代——仙盟创梦IDE

一、启动未来之窗AI 二、初始化数据接口三、便捷接口数据进入东方仙盟获取接口标准四、同步参数仙界界牌&#xff0c;冥界界牌&#xff0c;仙盟界牌 五、开始同步六、东方仙盟青云剑魂架构在当今数字化浪潮下&#xff0c;数据的采集、处理与传输成为众多应用场景的核心需求。而…

Rust 仿射类型(Affine Types)

在 Rust 中&#xff0c;仿射类型&#xff08;Affine Types&#xff09; 是所有权系统的理论基础&#xff0c;它规定了每个值有且仅有一次使用机会。这与线性类型&#xff08;必须恰好使用一次&#xff09;有所不同&#xff0c;允许值未被使用就被丢弃。Rust 中的仿射类型核心特…

python库 arrow 库的各种案例的使用详解(更人性化的日期时间处理)

文章目录 一、arrow概述1.1 arrow介绍1.2 安装 arrow1.3 注意事项二、基本使用2.1 创建 Arrow 对象2.2 格式化输出2.3 时间运算三、高级功能3.1 时区处理3.2 时间范围3.3 时间间隔四、实际应用案例4.1 日志时间处理4.2 会议时间提醒4.3 国际化时间显示5. Arrow 与 datetime 互操…

window 服务器上部署前端静态资源以及nginx 配置

最近搞了一台境外服务器 这种境外服务器是不可以配置域名的 但是可以使用ip访问 但是如果需要 配置 需要下载nginx nginx: download 我这个是windows 的 服务器 所以下载windows 的nginx 下载完成以后 这个里面的html 文件 就是前端项目 里面必须要有index.html文件 部署…

行业实践案例:医疗行业数据治理的挑战与突破

“医疗数据不仅是资源,更关乎生命。” ——医疗行业的数据治理,是合规、安全、质量与智能化的多重挑战。 📘 本文目录 为什么医疗行业亟需数据治理? 医疗行业数据治理的独特挑战 医疗数据治理体系设计原则 关键能力模块与实践案例 工具选型与落地建议 总结与下一步 1️⃣ …

单细胞转录组学和空间转录组学数据的整合方法

文章目录问题1&#xff1a;现有技术是否可以拿取固定数目的细胞进行组合形成spot问题2&#xff1a;是否有关于这方面的研究问题3&#xff1a;相关论文推荐一、细胞反卷积的核心目标与挑战二、单细胞与空间转录组数据的整合方法分类1. 概率型方法&#xff08;Probabilistic-base…

【Java EE】SpringBoot 配置文件、日志和单元测试

1. 什么是配置文件在我们的计算机上诸如 C:/Users&#xff0c;C:/Windows&#xff0c;.config&#xff0c;.xml 都是配置文件&#xff0c;配置文件主要为了解决硬编码带来的问题。硬编码是将数据直接写在程序的源代码中&#xff0c;代码写死后再想改变就很麻烦。因此&#xff0…

CMake实践:常见的调试技巧

目录 1.简介 2.用 message() 输出关键信息 2.1.message简介 2.2.常用模式及作用 2.3.核心用法示例 2.4.常见问题及解决 3.查看缓存变量&#xff1a;cmake -L 与缓存文件 3.1.列出所有缓存变量&#xff08;cmake -L&#xff09; 3.2.直接查看 / 删除 CMakeCache.txt 4…

爬虫-第一个爬虫程序

浏览器里面都是html数据&#xff0c;拿到的都是页面源代码&#xff0c;可以用自己的方式打开测试。打开浏览器decode找charset

从SEO到GEO:优化策略如何应对传统搜索与AI搜索的巨变

AI 搜索与传统搜索结果优化之间有什么重叠之处&#xff1f; 为了帮助确定主要的差异&#xff0c;以及那些重叠程度最高的区域&#xff0c;我创建了一个比较&#xff08;我会保持更新&#xff09;&#xff0c;通过搜索行为、优化领域、结果展示和交付&#xff0c;以及要跟踪的 K…

mysql5.7系列-InnoDB的MVCC实现原理

谈到数据库事务都要提一下ACID 特性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务中的操作要么全部执行&#xff0c;要么全部不执行。 一致性&#xff08;Consistency&#xff09;&#xff1a;事务执行前后&#xff0c;数据库的状态必须是一致的。 …

力扣-287.寻找重复数

题目链接 287.寻找重复数 class Solution {public int findDuplicate(int[] nums) {int low nums[0];int fast nums[nums[0]];//1.快慢指针找相遇点while (low ! fast) {low nums[low];fast nums[nums[fast]];}//2.双指针找入环点int pre 0;while (pre ! low) {pre num…

Java 大视界 -- Java 大数据在智能教育个性化学习计划制定与动态调整中的应用(338)

Java 大视界 -- Java 大数据在智能教育个性化学习计划制定与动态调整中的应用&#xff08;338&#xff09; 引言&#xff1a;正文&#xff1a;一、Java 构建的学习行为数据采集与分析体系1.1 全场景数据接入引擎1.2 家校协同数据交互模块1.3 学习特征提取与建模 二、Java 驱动的…

uniapp返回webview返回小程序并且跳转回webview

webview页面提示&#xff1a;wx一定要导入sdk// 返回小程序&#xff0c;并携带当前 WebView 的 URL 和状态wx.miniProgram.postMessage({type: requestPayment,data: {webviewUrl: window.location.href,orderNum: this.orderNum,type: requestPayment}})setTimeout(() > {w…