Nuxt 3.0 全栈开发:五种数据获取 API 选择和应用最佳实践

news2024/12/26 0:58:51

Nuxt 3.0 全栈开发 - 杨村长 - 掘金小册核心知识 + 工程架构 + 全栈进阶 + 项目实战,快速精通 Nuxt3 开发!。「Nuxt 3.0 全栈开发」由杨村长撰写,299人购买https://s.juejin.cn/ds/S6p7MVo/

上一讲我们学习了如何基于 API Route 编写接口,有了接口就需要获取数据,Nuxt3 中提供的多种数据访问 API:

  • $fetch;

  • useAsyncData;

  • useLazyAsyncData;

  • useFetch;

  • useLazyFetch。

为什么需要 $fetch?

前面说过,如果开发团队有服务端,并且接口已经开发完毕,则我们可以直接调用这些接口。但是由于我们是服务端渲染,不得不考虑接口的调用时机问题:

  • 首屏渲染,调用发生在服务端;
  • 客户端激活之后,调用发生在客户端。

这导致我们首先需要判断代码执行环境,其次发送请求的 API 可能不同,另外如果在客户端发送请求到其他接口服务器还会存在跨域问题,需要给项目配代理,很复杂是吧!这就是 Nuxt3 为什么替我们封装了 $fetch ,它全局可用,可以智能处理调用时机,还能统一 API,避免配置代理

Nuxt3 数据访问 API

上节课我们用到了$fetch,我们会像下面这样使用它:

const { data } = await $fetch('/api/hello', { query: { name: 'tom' } })
const { result } = await $fetch('/api/post', { method: 'post', body: newPost })

可以看到,$fetch 的 API 和 fetch 是一样的,实际调用的是 unjs/ofetch。它的用法符合我们之前的编码习惯,返回 Promise,然后用户负责处理后续操作。但如果要加上一些其他 loading、error 等反馈,我们通常要添加额外组件状态来实现,比较繁琐。

后来到了 hooks 时代,React 社区出现了诸如 ahooks、swr 等库,通过封装请求,暴露出 data、loading、error 等状态,然后可以在组件内直接使用,非常高效。Nuxt3 也为我们提供了四个接口,通过封装 $fetch,给用户提供响应式数据便于直接使用。下面我们一起来看一下它们的使用方式异同:

useFetch

页面、组件或者插件中可以使用useFetch获取任意 URL 资源。useFetch是对useAsyncData$fetch的封装,只需传入请求的 URL 或者一个请求函数即可,一些选项会自动填入,用起来最简洁,是最推荐的数据获取方式。

useFetch方法签名:

function useFetch(
  url: string | Request | Ref<string | Request> | () => string | Request,
  options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT>>

type AsyncData<DataT> = {
  data: Ref<DataT> // 返回数据
  pending: Ref<boolean> // 加载状态
  refresh: (opts?: { dedupe?: boolean }) => Promise<void> // 刷新数据
  execute: () => Promise<void> // 同 refresh,没有去重选项
  error: Ref<Error | boolean> // 错误信息
}

我们实践一下,将前面的博客列表获取操作重构为useFetch()方式。

很明显,我们处理各种状态更便捷了!index.vue:

<template>
  <div class="flex items-center flex-col gap-2 py-4">
    <!-- 处理请求错误 -->
    <div v-if="error" class="text-red-300">{{ error.message }}</div>
    <!-- 处理加载状态 -->
    <div v-if="pending">加载中...</div>
    <div v-else>
        <div v-for="post in posts" :key="post.id">
          <NuxtLink class="text-lg" :to="`/detail/${post.id}`">{{
            post.title
          }}</NuxtLink>
          <p class="text-slate-500">发布于: {{ post.date }}</p>
        </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  // const posts = await $fetch("/api/posts");
  const { data: posts, pending, error } = await useFetch('/api/posts')
</script>

useLazyFetch

该方法等效于useFetch设置了lazy选项为 true,不同之处在于它不会阻塞路由导航,这意味着我们需要处理 data 为 null 的情况(或者通过 default 选项给 data 设置一个默认值)。

前面的例子,将 useFetch 替换为 useLazyFetch 同样可行:

const { data: posts, pending, error } = await useLazyFetch('/api/posts')

useAsyncData

下面说一下useAsyncData,该方法和 useFetch 相比功能上是相同的,但是更底层,使用方法类似于 ahooks 库中的 useRequest,我们需要提供一个用于缓存去重的 key 和数据请求的处理函数。也就是说,useFetch 相当于:useAsyncData(key, () => $fetch(url))

useAsyncData签名如下,因此 useAsyncData 有两种用法:一种传 key,一种不传 key,但是即使你不传,Nuxt 也会帮你生成一个,所以该用哪个不用我说了吧!?

function useAsyncData(
  handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
  options?: AsyncDataOptions<DataT>
): AsyncData<DataT>
function useAsyncData(
  key: string,
  handler: (nuxtApp?: NuxtApp) => Promise<DataT>,
  options?: AsyncDataOptions<DataT>
): Promise<AsyncData<DataT>>

我们实践一下,用 useAsyncData 获取文章内容数据,detail/[id].vue:

<template>
  <div class="p-5">
    <div v-if="pending">加载中...</div>
    <div v-else>
      <h1 class="text-2xl">{{ data?.title }}</h1>
      <div v-html="data?.content"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
const router = useRoute();
const fetchPost = () => $fetch(`/api/detail/${router.params.id}`);
const { data, pending } = await useAsyncData(fetchPost);
</script>

useLazyAsyncData

该方法等效于useAsyncData,仅仅设置了lazy选项为true,也就是它不会阻塞路由导航,这意味着我们需要处理 data 为 null 的情况,或者通过 default 选项给 data 设置一个默认值。

刷新数据

有时候页面数据是需要刷新的,比如:翻页、条件过滤、搜索等。

我们可以使用useFetch()等 API 返回的refresh()刷新数据。需要注意,如果请求的 key 参数没有发生变化,我们实际上拿到的还是之前缓存的结果。例如下面代码执行 refresh()并不会得到最新数据:

const { data, refresh } = useFetch('/api/somedata')
// 数据并没有刷新!
refresh()

而想要获取最新数据,就要在 url 中添加一个参数,并作为函数返回值传给useFetch

// url需要改为由函数返回
const { data, refresh } = useFetch(() => `/api/somedata?page=${page}`)
// 数据刷新!
page++
refresh()

范例:分页获取文章列表

下面的范例在请求参数上添加一个页码,则页码变化后再刷新就可以得到最新的数据了,index.vue:

<script setup lang="ts">
const page = ref(1);
const {
  data: posts,
  pending,
  error,
  refresh, // 获取刷新函数
} = await useFetch(() => `/api/posts?page=${page.value}&size=2`); // 注意修改为工厂函数方式

function prev() {
  page.value--;
  refresh();
}

function next() {
  page.value++;
  refresh();
}
</script>

相应的,我们需要修改 posts 接口,posts.ts:

export default defineEventHandler((event) => {
  // 获取当前页码 page
  const query = getQuery(event);
  const page = Number(query.page);
  const size = Number(query.size);

  // ...
  // 降序排列、分页
  const start = (page - 1) * size;
  const end = start + size;
  return posts
    .sort((a, b) => (a.date < b.date ? 1 : -1))
    .slice(start, end);
});

总结

到这里我们全面了解了 Nuxt3 中各种数据请求 API 的使用方法。如果大家有选择困难症,我建议大家减少选项,因为 useFetch 本质上是高层封装,可以完全替代其他几个 API,另外如果我们还是想使用传统的数据获取方式,那就选择 $fetch就好了!

下次预告

解决数据获取的任务之后,下一步就是状态管理了,Nuxt3 有一个内置的 useState 方法可以用于全局状态的管理,当然我们也会整合 Pinia 到项目中以便满足后面项目开发需要。

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

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

相关文章

12.2 基于Django的服务器信息查看应用(CPU信息)

文章目录CPU信息展示图表展示-视图函数设计图表展示-前端界面设计折线图和饼图展示饼图测试折线图celery和Django配合实现定时任务Windows安装redis根据数据库中的数据绘制CPU折线图CPU信息展示 图表展示-视图函数设计 host/views.py def cpu(request):logical_core_num ps…

【Unity VR开发】结合VRTK4.0:创建人工按钮

语录&#xff1a; 人生需要准备的&#xff0c;不是昂贵的茶&#xff0c;而是喝茶的心情。 前言&#xff1a; 按钮按下抬起是虚仿中经常会出现的功能&#xff0c;那么如何去表现呢&#xff0c;我们可以使用线性变换驱动器对人工按钮进行装箱&#xff0c;以对来自交互器的碰撞做…

Netty——心跳机制与断线重连

心跳机制与断线重连心跳机制IdleStateHandler客户端服务端测试正常情况异常情况总结断线重连为了保证系统的稳定性&#xff0c;心跳机制和断线重连可是必不可少的&#xff0c;而这两个在Netty中也是非常好实现的心跳机制 我们以客户端发送心跳为例&#xff0c;平时我们的心跳实…

linux常用命令介绍 04 篇——uniq命令使用介绍(Linux重复数据的统计处理)

linux常用命令介绍 04 篇——uniq命令使用介绍&#xff08;Linux重复数据的统计处理&#xff09;1. uniq 使用语法2. sort 简单效果3. uniq 使用例子3.1 不加任何选项3.1.1 不用 sort 效果3.1.2 uniq 结合 sort 一起使用3.2 使用选项例子3.2.1 去重打印&#xff08;或打印不重复…

12 nuxt3学习(配置)

链接: nuxt3官网 nuxt简介 vue3技术栈&#xff1a;Nuxt3 是基于 Vue3 Vue Router Vite 等技术栈&#xff0c;全程 Vue3Vite 开发体验&#xff08;Fast&#xff09;。自动导包&#xff1a;Nuxt 会自动导入辅助函数、组合 API和 Vue API &#xff0c;无需手动导入。 基于规范…

卡方分布、非中心卡方分布详解 (概念、求阈值方法、非中心化参数求解办法等)

一、相关概念 1、卡方分布 若n个 相互独立 的随机变量 ξ₁、ξ₂、……、ξn ,均服从 标准正态分布N(0,1),则这n个服从标准正态分布的随机变量的 平方和 构成一新的随机变量,其分布规律称为卡方分布(chi-squaredistribution);其中参数n称为自由度(通俗讲,样本中独立…

有关数据库的一级、二级、三级封锁协议

一级封锁协议 一级封锁协议是指&#xff0c;事务T在修改数据R之前必须先对其加X锁&#xff0c;直到事务结束才释放。事务结束包括正常结束&#xff08;COMMIT&#xff09;和非正常结束&#xff08;ROLLBACK).一级封锁协议可防止丢失修改&#xff0c;并保证事务T是可恢复的。在…

SpringBoot热部署

启动热部署 关于热部署 重启&#xff08;Restart&#xff09;&#xff1a;自定义开发代码&#xff0c;包含类、页面、配置文件等&#xff0c;加载位置restart类加载器重载&#xff08;ReLoad&#xff09;&#xff1a;jar包&#xff0c;加载位置base类加载器开启开发者工具 导…

gma 地理空间绘图:(1) 绘制简单的世界地图-2.设置经纬网

内容回顾 gma 地理空间绘图&#xff1a;(1)绘制简单的世界地图-1.地图绘制与细节调整 方法 AddGridLines(LONRange (-180, 180, 15), LATRange (-90, 90, 15), ShowLON True, ShowLAT True, LineColor ‘gray’, LineStyle (0, (6, 6)), LineWidth 0.3) 功能&#xf…

10种常见网站安全攻击手段及防御方法

在某种程度上&#xff0c;互联网上的每个网站都容易遭受安全攻击。从人为失误到网络罪犯团伙发起的复杂攻击均在威胁范围之内。 网络攻击者最主要的动机是求财。无论你运营的是电子商务项目还是简单的小型商业网站&#xff0c;潜在攻击的风险就在那里。 知己知彼百战不殆&…

MOA-30kV氧化锌避雷器泄露电流测试仪

一、概述 用于检测10kV及以下电力系统用无间隙氧化锌避雷器MOA阀电间接触不良的内部缺陷&#xff0c;测量MOA的直流参考电压&#xff08;U1mA&#xff09;和0.75 U1mA下的泄漏电流。该仪器将直流高压电源、测量和控制系统组成一体&#xff0c;元件浓缩在一个机箱内&#xff0c…

JS混淆加密:Eval的未公开用法

JavaScript奇技淫巧&#xff1a;Eval的未公开用法 作者&#xff1a;http://JShaman.com w2sft&#xff0c;转载请保留此信息很多人都知道&#xff0c;Eval是用来执行JS代码的&#xff0c;可以执行运算、可以输出结果。 但它还有一种未公开的用途&#xff0c;想必很少有人用过。…

【计算机网络】数据链路层:组帧,奇偶校验,CRC循环冗余校验,海明码详解

数据链路层 一、校验 1. 奇偶校验 偶校验 数据位和为偶数&#xff1a;校验位为0&#xff1b;数据位和为奇数&#xff1a;校验位为1&#xff1b; 奇校验 数据位和为奇数&#xff1a;校验位为0&#xff1b;数据位和为偶数&#xff1a;校验位为1&#xff1b; 缺点是会存在误判…

【Autoware】采集实验数据bag包并仿真运行

文章目录1. 官方demo包2. 控制底层地图采集3. 感知定位4. 规划控制5. 仿真或实车运行1. 官方demo包 wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_data.tar.gz wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_150324.tar.gz官方示例包的网上…

iPhone屏蔽APP广告的方法

iPhone怎么屏蔽网站(域名)&#xff1f; 操作步骤&#xff1a;“设置” -> “屏幕使用时间” -> “打开屏幕使用时间” -> “内容和隐私访问限制” -> “内容访问限制” -> “网页内容” -> “限制成人网站” -> “永不允许”, 添加需要屏蔽的网站或者域名…

项目开发过程中实际遇到的几个问题处理

1、今天开发环境运行的时候出现下面问题 The project cannot be built until build path errors are resolved. 出现报错情况&#xff0c;之前也没有遇到过。 根据字面意思“在解决生成路径的错误之前&#xff0c;无法生成项目”&#xff0c;也就是说项目的路径位置配置错误…

【论文速递】CVPR2021 - 基于自引导和交叉引导的小样本分割算法

【论文速递】CVPR2021 - 基于自引导和交叉引导的小样本分割算法 【论文原文】&#xff1a;Self-Guided and Cross-Guided Learning for Few-Shot Segmentation 【作者信息】&#xff1a;Bingfeng Zhang, Jimin Xiao , Terry Qin 获取地址&#xff1a;https://openaccess.the…

来香港饮茶吹水先,免费报名Zabbix Meetup香港站!

Zabbix Meetup 来到香港啦&#xff01; 春暖花开&#xff0c;Zabbix计划5月来到香港&#xff0c;和你一起饮茶吹水&#xff01; 时间&#xff1a;5月某日&#xff0c;周几方便&#xff1f; 预计14:00-17:00 形式&#xff1a;线下交流会&#xff0c;免费&#xff0c;线下&…

测评自养号优势,亚马逊,速卖通、美客多、Newegg等跨境卖家必看!

随着跨境电商的发展&#xff0c;越来越多有实力的商家加入到跨境电商的行列&#xff0c;导致行业竞争越来越大&#xff0c;成本投入也越来越高&#xff0c;原来的跨境蓝海已经变红海&#xff0c;卖家都不得不靠“烧钱”来提升排名&#xff0c;吸引流量从而维持销量。那么卖家如…

企业电子招投标采购系统——功能模块功能描述

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…