大家好,这里是大家的林语冰。
《前端猫猫教》每日 9 点半更新,坚持阅读,自律打卡,每天一次,进步一点。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 7 New Features in Nuxt 3.9。

本期共享的是 ------ Nuxt 3.9 版本中值得注意的七大新功能。
Nuxt 3.9 中有很多新内容,本人花了一些时间深度学习其中的某些内容。在这篇文章中,我会介绍:
- 调试生产环境中的水合错误
- 新型的
useRequestHeader
组合式函数 - 自定义布局备案
- 将依赖添加到我们的自定义插件
- 对加载 UI 进行细粒度控制
- 新型好用的
callOnce
组合式函数 - 请求去重:适用于
useFetch
和useAsyncData
组合式函数
1. 调试生产环境中的水合错误
水合错误(hydration error)是 SSR(服务端渲染)最头大的部分之一,尤其当且仅当它们发生在生产环境中时。
幸运的是,Vue 3.4 让我们可以搞定这一点。
在 Nuxt 中,我们需要做的就是更新我们的配置:
js
export default defineNuxtConfig({
debug: true
// 你的其余配置......
})
如果您没有使用 Nuxt,那么可以使用新型编译时标志,从而启用此功能:__VUE_PROD_HYDRATION_MISMATCH_DETAILS__
。这就是 Nuxt 使用的方案。
根据您使用的构建工具,启用标志会有所不同,但如果我们使用的是 Vite,那就在 vite.config.js
文件配置,如下所示:
js
import { defineConfig } from 'vite'
export default defineConfig({
define: {
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true'
}
})
启动此功能会增加我们的打包体积,但它对于追踪那些令人头大的水合错误十分有用。
2. useRequestHeader 组合式函数
在 Nuxt 中,从请求中获取单个 header 轻而易举:
js
const contentType = useRequestHeader('content-type')
这在中间件和服务器路由中,用来检查身份验证或其他许多事情都十分方便。
如果我们在浏览器环境使用 useRequestHeader
组合式函数,那么它会返回 undefined
。
这是 useRequestHeaders
的抽象,因为很多时候我们只需要一个 header。
3. Nuxt 布局备案(layout fallback)
如果我们正在 Nuxt 中处理复杂的 Web App,那我们可能需要更改默认布局:
html
<NuxtLayout fallback="differentDefault">
<NuxtPage />
</NuxtLayout>
通常,如果没有指定其他布局,NuxtLayout
组件会使用 default
布局 ------ 通过 definePageMeta
、setPageLayout
,或直接指定 NuxtLayout
组件本身。
这对于大型 App 而言十分有用,我们可以在其中为 App 的每个部分提供不同的默认布局。
4. Nuxt 插件依赖
为 Nuxt 编写插件时,可以指定依赖:
js
export default defineNuxtPlugin({
name: 'cat-plugin',
dependsOn: ['another-plugin']
async setup (nuxtApp) {
// setup() 方法只会在 another-plugin 插件初始化后运行一次
}
})
但为什么我们需要这个功能呢?
通常,插件是根据它们在文件系统中的顺序依次初始化的:
md
plugins/
- 01.firstPlugin.ts // 使用数字强制排序,而非字母顺序
- 02.anotherPlugin.ts
- thirdPlugin.ts
但我们也可以并行加载它们,如果它们不相互依赖的话,这会加快速度:
js
export default defineNuxtPlugin({
name: 'my-parallel-plugin',
parallel: true,
async setup(nuxtApp) {
// 完全独立于所有其他插件运行
}
})
虽然但是,有时我们有其他插件依赖于这些并行插件。通过使用 dependsOn
属性,我们可以让 Nuxt 知道我们需要等待哪些插件,即使它们是并行运行的:
js
export default defineNuxtPlugin({
name: 'cat-plugin',
dependsOn: ['parallel-plugin']
async setup (nuxtApp) {
// 在初始化之前会等待 parallel-plugin 并行插件完成
}
})
尽管十分有用,但我们实际上可能并不需要此功能。有大佬曾经说过,"我个人不会在插件中使用这种硬性依赖图。钩子函数在依赖关系定义方面更加灵活,并且可以肯定每种情况都可以用正确的模式解决。考虑到历史上这一直是一个被社区要求的功能,私以为它主要是 Nuxt 作者的'差评去质器'。"
5. Nuxt 加载API
在 Nuxt 中,我们可以获得有关如何使用 useLoadingIndicator
组合式函数加载页面的详细信息:
js
const { progress, isLoading } = useLoadingIndicator()
console.log(`Loaded ${progress.value}%`) // 进度 9%
这在 <NuxtLoadingIndicator>
组件内部使用,并且如果我们正在编写插件,这可以通过 page:loading:start
和 page:loading:end
钩子触发。
但我们对加载指示器的运行方式有很多控制权:
js
const {
progress,
isLoading,
start, // 从零开始
set, // 进度重写
finish, // 完成和清理
clear // 清空所有 timer 和重置
} = useLoadingIndicator({
duration: 996, // 默认值 2000
throttle: 996 // 默认值 200
})
我们可以专门设置 duration
,这是我们需要的,这样我们可以将 progress
计算为百分比。throttle
值控制 progress
值更新的速度 ------ 如果我们有大量预期平滑的交互,那就十分有用。
finish
和 clear
之间的区别至关重要。虽然 clear
重置所有内部计时器,但它不会重置任何值。
为此我们需要 finish
方法,它可以实现更优雅的用户体验。finish
将 progress
设置为 100
,将 isLoading
设置为 true
,然后等待半秒。之后,它会把所有值重置回初始状态。
6. Nuxt callOnce
如果我们只需要运行一段代码一次,那可以使用 Nuxt 专门的组合式函数,从 Nuxt 3.9 开始提供:
html
<script setup>
await callOnce(async () => {
// 即使是 SSR,这也有且仅有运行一次
});
</script>
使用 callOnce
可确保我们的代码有且仅有执行一次 ------ 无论是 SSR 期间在服务器上执行,还是在用户导航到新页面时在客户端上执行。
我们可以将其理解为为类似于路由中间件 ------ 每个路由加载有且仅有执行一次。但是 callOnce
不返回任何值,并且可以在可以放置组合式函数的任意位置执行。
callOnce
还有一个类似于 useFetch
或 useAsyncData
的属性,这确保它可以追踪已执行的内容和未执行的内容:
html
<script setup>
;['one', 'two', 'three'].forEach(item => {
// 为每个元素执行一次
callOnce(item, async () => {
// 处理元素的逻辑
})
})
</script>
默认情况下,Nuxt 将使用文件和行号自动生成唯一密钥,但这并非在所有情况下都奏效。
7. Nuxt 中的重复请求
从 Nuxt 3.9 开始,我们可以使用 dedupe
参数控制 Nuxt 去重的方式:
js
useFetch('/api/menuItems', {
dedupe: 'cancel' // 取消之前的请求,生成一个新的请求
})
useFetch
和 useAsyncData
组合式函数会在其参数更新时响应式重新请求数据。默认情况下,它们会取消之前的请求,并使用新参数发起新的请求。
虽然但是,我们可以将此行为更改为现有请求,而不是 defer
------ 当存在待处理请求时,不会发出新请求:
js
useFetch('/api/menuItems', {
dedupe: 'defer' // 保留待定请求,不会初始化新请求
})
这使我们能够更好地控制数据加载和请求的方式。
本期话题是 ------ 你个人最喜欢的是 Nuxt 3.9 的哪个新功能呢?
欢迎在本文下方自由言论,文明共享。谢谢大家的点赞,掰掰~
《前端猫猫教》每日 9 点半更新,坚持阅读,自律打卡,每天一次,进步一点。
