Nuxt 是一个全栈框架,这意味着在不同的上下文中可能会发生一些无法预防的运行时用户错误,来源包括:
server/ 目录)你可以使用 onErrorCaptured 钩子来捕获 Vue 错误。
此外,Nuxt 提供了一个 vue:error 钩子,如果任何错误向上冒泡到顶层,该钩子将被调用。
如果你在使用错误上报框架,可以通过 vueApp.config.errorHandler 提供一个全局处理器。它会接收所有 Vue 错误,即使这些错误已被处理。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
// 处理错误,例如上报到服务
}
// 也可以这样使用
nuxtApp.hook('vue:error', (error, instance, info) => {
// 处理错误,例如上报到服务
})
})
vue:error 钩子是基于 onErrorCaptured 生命周期钩子。如果在启动 Nuxt 应用时发生任何错误,Nuxt 会调用 app:error 钩子。
这包括:
app:created 和 app:beforeMount 钩子onErrorCaptured 或 vue:error 来处理这种情况)app:mounted 钩子目前你无法为这些错误定义服务器端处理器,但可以渲染错误页面,参见 渲染错误页面 部分。
你可能会遇到 chunk 加载错误,原因是网络连接失败或新的部署(使旧的带哈希的 JS chunk URL 失效)。Nuxt 内置了处理 chunk 加载错误的支持:在路由导航期间如果某个 chunk 加载失败,会执行硬刷新。
你可以通过将 experimental.emitRouteChunkError 设置为 false(完全禁用对这些错误的钩取)或设置为 manual(如果你想自行处理它们)来更改此行为。如果你想手动处理 chunk 加载错误,可以查看 自动实现 以获取灵感。
fatal: true 创建的错误)时,它将根据请求头决定要么渲染 JSON 响应(如果请求带有 Accept: application/json),要么触发一个全屏错误页面。在服务器生命周期中可能发生错误的情况包括:
在客户端也可能发生错误的情况包括:
app:beforeMount 钩子)onErrorCaptured 或 vue:error 钩子处理,在挂载应用时发生错误app:mounted)通过在应用源目录中(与 app.vue 并列)添加 ~/error.vue 来自定义默认错误页面。
<script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({
error: Object as () => NuxtError,
})
const handleError = () => clearError({ redirect: '/' })
</script>
<template>
<div>
<h2>{{ error?.statusCode }}</h2>
<button @click="handleError">
清除错误
</button>
</div>
</template>
对于自定义错误,我们强烈建议使用 onErrorCaptured 可组合函数(可在页面/组件的 setup 函数中调用)或在 Nuxt 插件中配置的运行时 vue:error 钩子。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('vue:error', (err) => {
//
})
})
当你准备移除错误页面时,可以调用 clearError 帮助函数,它接受一个可选的重定向路径(例如,如果你想导航到一个“安全”页面)。
$route 或 useRouter)之前,请务必先检查,因为如果某个插件抛出了错误,该插件在清除错误之前不会重新运行。useError 来检查是否正在处理错误。useErrorfunction useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>
此函数将返回当前正在处理的全局 Nuxt 错误。
createErrorfunction createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
创建一个带有附加元数据的错误对象。你可以传入字符串作为错误的 message,也可以传入包含错误属性的对象。该函数可在应用的 Vue 和服务器部分使用,并且用于抛出错误。
如果你抛出由 createError 创建的错误:
clearError 来清除。fatal: true 来实现。<script setup lang="ts">
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)
if (!data.value) {
throw createError({
statusCode: 404,
statusMessage: '未找到页面',
})
}
</script>
showErrorfunction showError (err: string | Error | { statusCode, statusMessage }): Error
你可以在客户端的任意时刻调用此函数,或者在服务器端直接在中间件、插件或 setup() 函数内调用。它会触发一个全屏错误页面,你可以使用 clearError 来清除。
建议改为使用 throw createError()。
clearErrorfunction clearError (options?: { redirect?: string }): Promise<void>
此函数将清除当前正在处理的 Nuxt 错误。它还接受一个可选的重定向路径(例如,如果你想导航到一个“安全”页面)。
Nuxt 还提供了一个 <NuxtErrorBoundary> 组件,允许你在应用内处理客户端错误,而无需将整个站点替换为错误页面。
该组件负责处理发生在其默认插槽中的错误。在客户端,它会阻止错误向顶层冒泡,并渲染 #error 插槽作为替代。
#error 插槽将接收 error 作为 prop。(如果你将 error = null,它会触发默认插槽的重新渲染;你需要确保错误已被完全解决,否则错误插槽将再次被渲染。)
<template>
<!-- 一些内容 -->
<NuxtErrorBoundary @error="someErrorLogger">
<!-- 使用默认插槽渲染内容 -->
<template #error="{ error, clearError }">
你可以在这里本地显示错误: {{ error }}
<button @click="clearError">
清除错误
</button>
</template>
</NuxtErrorBoundary>
</template>