Nuxt3封装网络请求 useFetch $fetch

前言:

刚接触、搭建Nuxt3项目的过程还是有点懵的,有种摸石头过河的感觉,对于网络请求这块,与之前的Vue3项目有所区别,在Vue项目通常使用axios这个库进行网络请求,但在Nuxt项目并不推荐,因为有内置 fetch 相关...接下来一起学习一下Nuxt3数据请求的点点滴滴吧~

文档:

数据获取 · 快速入门 Nuxt

关键:

  • useFetch 是在组件设置函数中处理数据获取的最简单方法。
  • $fetch 可以根据用户交互进行网络请求。
  • useAsyncData 结合 $fetch,提供了更精细的控制。

讲解:

useAsyncData:
  • 提供了一种在SSR友好的组合式中访问异步解析数据的方式
  • 注意,setup期间,这里结合了$fetch,并且设置了一个key,一个唯一的键,用于确保数据获取可以在请求中正确去重
  • <script setup>
    const { data, pending, error, refresh } = await useAsyncData('mountains',() => $fetch('https://api.nuxtjs.dev/mountains')
    )
    </script>
  • 当 CMS 或第三方提供自己的查询层时。在这种情况下,您可以使用 useAsyncData 来封装您的调用,并仍然保持组合函数提供的好处。 
$fetch:
  • Nuxt使用 ofetch 来全局暴露`$fetch`辅助函数,用于在Vue应用程序或API路由中进行HTTP请求 
  • 源码:nuxt/packages/nuxt/src/app/entry.ts at main · nuxt/nuxt · GitHub
  • $fetch是在Nuxt中进行HTTP调用的首选方式,而不是为Nuxt 2设计的@nuxt/http和@nuxtjs/axios。
  • 比如,你的页面有给用户提供交互的(按钮),那么就可以使用 $fetch ,不然控制台会有警告,网上就有不少人是在交互的时候使用useFetch而出现问题,看下面这篇文章
  • 警告:[nuxt] [useFetch] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching
  • Nuxt 3:正确的方法 --- useFetch in Nuxt 3: The Proper Way (alex.party)
  • 请观察以下调用接口的时机:setup | click
  • <script setup lang="ts">
    // 在SSR中数据将被获取两次,一次在服务器端,一次在客户端。
    const dataTwice = await $fetch('/api/item')// 在SSR中,数据仅在服务器端获取并传递到客户端。
    const { data } = await useAsyncData('item', () => $fetch('/api/item'))// 你也可以使用useFetch作为useAsyncData + $fetch的快捷方式
    const { data } = await useFetch('/api/item')
    </script>
    <script setup lang="ts">
    function contactForm() {$fetch('/api/contact', {method: 'POST',body: { hello: 'world '}})
    }
    </script><template><button @click="contactForm">联系我们</button>
    </template>
useFetch :
  • 使用一个与SSR兼容的可组合函数从API端点获取数据。
  • 包装了useAsyncData和$fetch,它返回响应式的可组合函数,并处理将响应添加到Nuxt的负载中,以便在页面水合时可以从服务器传递给客户端,而无需在客户端重新获取数据。
  • (水合的概念在文档的渲染模式有讲解:渲染模式 · 关键概念 (nuxt.com.cn))
  • 提供了拦截器
  • const { data, pending, error, refresh } = await useFetch('/api/auth/login', {onRequest({ request, options }) {// 设置请求头options.headers = options.headers || {}options.headers.authorization = '...'},onRequestError({ request, options, error }) {// 处理请求错误},onResponse({ request, response, options }) {// 处理响应数据localStorage.setItem('token', response._data.token)},onResponseError({ request, response, options }) {// 处理响应错误}
    })
    
  • 事实上,useFetch(url) 几乎等同于 useAsyncData(url, () => $fetch(url)) - 它是为最常见的用例提供的开发者体验糖。 

封装:工厂函数设计请求代码结构

env:
  • 在nuxt.config.ts配置 runtimeConfig,通过useRuntimeConfig()解构,示例:
export default defineNuxtConfig({runtimeConfig: {public: {API_BASE_DEV: 'http://localhost:4000',API_BASE_PROD: 'https://api.example.com/v1'}},
})
  • 当然你还可以

 composables:
  • 封装$fetch
  • - composables/useDollarFetchRequest.ts
import { $fetch } from 'ofetch';
import { useRuntimeConfig } from '#app';interface RequestOptions {customBaseURL?: string;[key: string]: any;
}type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';// 请求拦截器
function handleRequest(options: RequestOptions) {options.headers = {...options.headers,'Content-Type': 'application/json',};
}// 响应拦截器
function handleResponse(response: any) {if (response.error) {throw new Error(response.error.message || '响应错误');}return response;
}/*** 创建请求方法* @param method*/
function createDollarFetchRequest(method: HttpMethod) {return async function (url: string,data?: any,options: RequestOptions = {}) {const {public: {API_BASE_DEV,API_BASE_PROD}} = useRuntimeConfig();const baseURL = process.env.NODE_ENV === 'production'? API_BASE_PROD: API_BASE_DEV;const requestUrl = new URL(url,options.customBaseURL || baseURL).toString();try {handleRequest(options);const response = await $fetch(requestUrl, {method,body: data,...options,});return handleResponse(response);} catch (error) {console.error('请求错误:', error);throw error;}};
}// 提供 $fetch & HTTP 方法 - 统一管理请求 - 再到组件中使用
export const useDollarGet = createDollarFetchRequest('GET');
export const useDollarPost = createDollarFetchRequest('POST');
export const useDollarPut = createDollarFetchRequest('PUT');
export const useDollarDelete = createDollarFetchRequest('DELETE');
  • 封装useFetch
  • - composables/useFetchRequest.ts
import { useFetch, useRuntimeConfig } from '#app';
import type { UseFetchOptions } from 'nuxt/app';interface RequestOptions extends UseFetchOptions<any> {customBaseURL?: string;
}type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type HandleRequestOptions = { request: Request; options: RequestOptions };
type HandleResponseOptions = { response: any };// 请求拦截器
function handleRequest({ options }: HandleRequestOptions) {options.headers = {...options.headers,'Content-Type': 'application/json',};
}// 响应拦截器
function handleResponse({ response }: HandleResponseOptions) {if (response._data.error) {throw new Error(response._data.error.message || '响应错误');}return response._data;
}/*** 创建请求方法* @param method*/
function createUseFetchRequest(method: HttpMethod) {return async function (url: string,data?: any,options: RequestOptions = {}) {const {public: {API_BASE_DEV,API_BASE_PROD}} = useRuntimeConfig();const baseURL = process.env.NODE_ENV === 'production'? API_BASE_PROD: API_BASE_DEV;const requestUrl = new URL(url,options.customBaseURL || baseURL).toString();return await useFetch(requestUrl, {...options,method,body: data,onRequest: handleRequest,onResponse: handleResponse});};
}// 提供 useFetch & HTTP 方法 - 统一管理请求 - 再到组件中使用
export const useFetchGet = createUseFetchRequest('GET');
export const useFetchPost = createUseFetchRequest('POST');
export const useFetchPut = createUseFetchRequest('PUT');
export const useFetchDelete = createUseFetchRequest('DELETE');
统一管理 API 
  • 调用 $fetch 示例:
import { useDollarGet } from '~/composables/useDollarFetchRequest';export const getDocsApi = () => useDollarGet('/docs/list');
<template><div><button @click="handleGetUserInfo">获取用户信息</button></div><HomeCover /><HomeIntro /><HomeCadre /><HomeJoinUs /><BackToTop />
</template><script setup lang="ts">
import HomeCover from './HomeCover.vue';
import HomeIntro from './HomeIntro.vue';
import HomeCadre from './HomeCadre.vue';
import HomeJoinUs from './HomeJoinUs.vue';
import { getDocsApi } from '../../api/home/joinUs';const handleGetUserInfo = async () => {try {const data = await getDocsApi();console.log('文档列表:', data);} catch (error) {console.error('获取文档列表出错:', error);}
};
</script>
  • 调用 useFetch 示例
<script setup lang="ts">
import { getDocsApi } from '../../api/home/joinUs';try {const response = await getDocsApi();console.log('文档列表:', response.data.value);
} catch (error) {console.error('获取文档列表出错:', error);
}</script>
结果:

 


 欢迎三连,以及在评论区讨论,如果有不对的还请告知纠正 

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

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

相关文章

RK3568平台(显示篇)主屏副屏配置

一.主屏副屏配置 目前在RK3568平台上有两路HDMIOUT输出&#xff0c;分别输出到两个屏幕上&#xff0c;一路配置为主屏&#xff0c;一路配置为副屏。 硬件原理图&#xff1a; &hdmi0_in_vp2 {status "okay"; };&hdmi1_in_vp0 {status "okay"; }…

axios使用sm2加密数据后请求参数多了双引号解决方法

axios使用sm2加密数据后请求参数多了双引号解决 背景问题描述解决过程 背景 因项目安全要求&#xff0c;需对传给后端的入参加密&#xff0c;将请求参数加密后再传给后端 前期将axios降低到1.6.7后解决了问题&#xff0c;但最近axios有漏洞&#xff0c;安全要求对版本升级&…

【Qt 初识 Test】用图形化和代码的方式实现简单的Qt程序

文章目录 1. 通过图形化的方式实现&#x1f34e;2. 通过代码的方式实现 1. 通过图形化的方式实现&#x1f34e; 在界面创建出一个控件&#xff0c;显示 hello world&#xff0c;通过拖拽的方式实现&#xff1b; widget.ui文件如下&#xff1a;&#x1f50d; 生成的 ui_widget.…

【mybatis】mybatisX插件概述

一、主要功能 智能补全与提示 MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息&#xff0c;从而显著提高开发效率。代码生成器 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器&#xff0c;但它可能集成了或支持与其他代码生成工具&#…

卤味江湖中,周黑鸭究竟该抓住什么赛点?

近年来&#xff0c;卤味江湖的决斗从未停止。 随着休闲卤味、佐餐卤味等细分赛道逐渐形成&#xff0c;“卤味三巨头”&#xff08;周黑鸭、绝味食品、煌上煌&#xff09;的牌桌上有了更多新对手&#xff0c;赛道变挤了&#xff0c;“周黑鸭们”也到了转型关键期。 这个夏天&a…

MySQL字符串相关数据处理函数

目录 1. 转大小写 2. 截取字符串 sunstr 3. 获取字符长度 4. 字符串拼接 concat 5. 去掉空白 trim 1. 转大小写 转大写&#xff1a;upper() 转小写&#xff1a;lower() 虽然MySQL不严格区分大小写&#xff0c;但是我们还是需要掌握这种大小写的操作以方便学习其他…

Nessus相关

tenable 1 安装nessus scanner 1 )安装nessus scanner: 方法一 curl -H X-Key: xxxxx https://cloud.tenable.com/install/scanner?namescanner-name&groupsscanner-group | bash方法二&#xff1a; **# for ubuntu, its https://www.tenable.com/downloads/api/v1/pu…

Google登录时人机身份验证的图片类型和通过的经验建议,以及一些常见问题

很多朋友在登录谷歌账号时&#xff0c;都遇到过要求人机身份验证的步骤&#xff0c;而且有一些时候人机身份验证这个步骤很让人纠结&#xff0c;甚至压根就出不来具体的验证图片&#xff0c;或者花了十几分钟、几十分钟都过不去。 所以今天GG账号服务就来为您解析一下谷歌登录…

初学SpringMVC之接收请求参数及数据回显

pom.xml 文件导入 lombok 的依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version></dependency> Controller 表示这是一个控制器 RequestParam 表示从前端接收…

夏日智启:我的Datawhale AI夏令营探索之旅

前言 最近几年&#xff0c;AI&#xff08;人工智能&#xff09;的发展呈现出了前所未有的迅猛势头&#xff0c;其影响力和应用范围不断扩大&#xff0c;深刻地改变着我们的生活、工作和社会结构。尤其是AI大模型技术&#xff0c;国内外可谓是“百模大战”&#xff0c;百舸争流…

github恢复码怎么备份

https://docs.github.com/zh/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication-recovery-methods

谷歌插件之一键关闭同域名页面

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 谷歌插件之一键关闭同域名页面 前言项目结构mainfest.jsonbackgroud.js 项目实现效果展示展望 前…

13019.CUDA问题积累

文章目录 1 内存不断增长的问题1.1 主机从GPU拷贝内存1.1.1 htop 内存增长到一定阶段后&#xff0c;保持稳定 1.2 GPU拷贝到Host修改之后内存稳定无变化1.3 结论 2 主机与GPU数据拷贝方案2.1 cudaMemcpy 拷贝内存2.2 cudaMemcpyAsync 异步数据拷贝2.3 采用多线程拷贝技术2.3.1 …

群主必学!轻松Get如何解散微信群的技巧

作为一个微信群的群主&#xff0c;解散群聊可能是你需要掌握的重要技能之一。不管是因为群聊的目的已经达成&#xff0c;还是因为群成员过少或不活跃&#xff0c;了解如何解散微信群都能帮助你更好地管理你的群聊。 如何解散微信群&#xff1f;本文将为您提供一些简单易行的技…

代码随想录算法训练营第五十天| 739. 每日温度、496.下一个更大元素 I、503.下一个更大元素II

739. 每日温度 题目链接&#xff1a; 739. 每日温度 文档讲解&#xff1a;代码随想录 状态&#xff1a;不会 思路&#xff1a; 这道题需要找到下一个更大元素。 使用栈来存储未找到更高温度的下标&#xff0c;那么栈中的下标对应的温度从栈底到栈顶是递减的。这意味着&#xff…

改变Ubuntu的Tab没有缩进4格(Makefile)

1.vim里的Tab 用vi指令打开这个文件&#xff0c;没有的话就新创建一个 vi ~/.vimrc在打开的文件中输入以下两行 1 set tabstop42 set shiftwidth4 ~ Esc &#xff1a; x&#xff0c;保存并退出即可 资料来源&#xff1a; 2024年5月21日-vi/vim …

Linux Ubuntu MySQL环境安装

1. 更新软件源 首先&#xff0c;确保你的Ubuntu系统已经更新了软件源列表&#xff0c;以便能够下载到最新的软件包。打开终端并输入以下命令&#xff1a; sudo apt update 2. 安装MySQL服务器 打开终端并输入以下命令来安装MySQL服务器 sudo apt install mysql-server 在…

一个便捷的web截图库~【送源码】

随着时间的发展&#xff0c;前端开发的范围越来越广&#xff0c;能够实现的功能也越来越多&#xff0c;要实现的功能也五花八门&#xff0c;今天就给大家介绍一个web截图库,让前端也能实现截图功能—— js-web-screen-shot js-web-screen-shot js-web-screen-shot 是一个基于 …

语言模型演进:从NLP到LLM的跨越之旅

在人工智能的浩瀚宇宙中&#xff0c;自然语言处理&#xff08;NLP&#xff09;一直是一个充满挑战和机遇的领域。随着技术的发展&#xff0c;我们见证了从传统规则到统计机器学习&#xff0c;再到深度学习和预训练模型的演进。如今&#xff0c;我们站在了大型语言模型&#xff…

【接口设计】如何设计统一 RESTful 风格的数据接口

如何设计统一 RESTful 风格的数据接口 1.版本控制1.1 通过 URL1.2 通过自定义请求头1.3 通过 Accept 标头 2.过滤信息3.确定 HTTP 的方法4.确定 HTTP 的返回状态5.定义统一返回的格式 近年来&#xff0c;随着移动互联网的发展&#xff0c;各种类型的客户端层出不穷。如果不统一…