choukin

V1

2022/07/22阅读:24主题:默认主题

[Nuxt 3] (八)状态管理&错误监听

状态管理

Nuxt 3 提供了 useState 组合项,创建跨组件的响应式和SSR友好的共享状态。

useState 是一种SSR 友好的,可替换`ref`[1] 。它的值将在服务端渲染后(在客户端起作用后)保留,并使用唯一的key 在组件之间共享。

useSate 只能在 setup 或者声明周期钩子函数中使用。

最佳实践

不要在<script setup>或者setup()函数之外定义const state = ref()
这样的状态会在访问你网站的所有用户使用,并且会导致内存泄漏!

应该使用 const useX = () => useState('x')

例子

基本用法

在这个例子中,我们使用组件局部计数器状态,使用useState('counter')的任何其他组件共享相同的响应状态。

<script setup>
const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script>

<template>
  <div>
    Counter: {{ counter }}
    <button @click="counter++">
      +
    </button>
    <button @click="counter--">
      -
    </button>
  </div>
</template>

进阶

在本例子中,我们使用了一个可组合程序,该程序从http请求头中检测用户的locle信息,并且保存到local中。

:LinkExample{link="/examples/other/locale"}

共享状态

通过使用auto-imported 组合项我们可以定义安全的数据状态,并在应用程序中使用它们。

export const useCounter = () => useState<number>('counter', () => 0)
export const useColor = () =>
 useState<string>('color', () => 'pink')
<script setup>
const color = useColor() // Same as useState('color')
</script>

<template>
  <p>Current color: {{ color }}</p>
</template>

错误处理

处理错误

Nuxt 3 是一个全栈框架,这意味着在不同上下文中会出现一些无法预防的用户运行时错误:

  1. 在Vue渲染的生命周期内的错误(SSR+SPA)
  2. 在AP或Nitro服务的生命周期内的错误
  3. 服务器和客户端启动的错误(SSR+SPA)

Vue 渲染时生命周期内的错误 (SSR + SPA)

你可以使用`onErrorCaptured`[2]监听Vue的错误

此外Nuxt提供了一个 vue:error 钩子,当有错误本抛到顶层时,会调用这个钩子。

如果你使用的是错误报告框架,你可以通过提供全局的处理程序。它将接收所有的Vue错误,即使它们已经被处理。

全局错误报告框架示例:

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.config.errorHandler = (error, context) => {
    // ...
  }
})

服务器和客户端启动错误S (SSR + SPA)

如果在启动Nuxt应用时报错,触发 app:error钩子 包括:

  • 运行Nuxt 插件
  • 处理 app:created app:beforeMount 钩子
  • 挂在app(在客户端),不过你应该使用onErrorCaptured或者vue:error来处理这种情况。
  • 处理 app:moounted 钩子。

在API 或者Nitro服务生命周期时报错

目前,无法在服务端处理这些程序,但你可以渲染一个错误页面(请参阅下一章)

渲染一个错误页面

当Nuxt 遇到致命错误时,无论是在服务器生命周期内,还是渲染Vue应用时(SSR 和 SPA).它都会响应一个JSON(如果请求时头部设置了 Accept: application/json)数据,或者一个HTML错误页面.

可以在项目中直接添加~/error.vue定义一个错误页面。 和app.vue 同级,这个页面有一个属性error,其中包含你要处理的错误信息。

当你打算离开错误页面时,你可以调用clearerror辅助函数,该函数接收一个可选的重定向路由参数(例如:你想要跳转到一个安全的页面)。

在确定使用任何Nuxt插件前比如$routeuseRouter ,一定要检查,就像插件报错一样,在你清除错误前,程序不会重新运行。

例子

<template>
  <button @click="handleError">Clear errors</button>
</template>

<script setup>
const props = defineProps({
  error: Object
})

const handleError = () => clearError({ redirect: '/' })
</script>

错误辅助方法

useError

  • function useError (): Ref<any>

这个方法返回一个正在处理的全局Nuxt错误。

throwError

  • function throwError (err: string | Error): Error

你可以在客户端的任意点调用这个方法,或者在服务端的中间件,插件或setup() 函数中调用,它会触发一个全屏错误页面,你可以使用clearError 清除该页面。

clearError

  • function clearError (options?: { redirect?: string }): Promise<void>

该函数将清除当前处理的Nuxt错误,它接收一个可选的重定向路径,(例如:你想要跳转到安全的页面)

应用程序中的渲染错误

Nuxt 还提供了一个<NuxtErrorBoundary>组件,允许你处理应用程序中的客户端错误,而无需用错误页面来替换整个错误站点。

此组件负责处理其默认插槽内发生的错误,在客户端,它将防止错误冒泡到顶层,并将渲染内部的 #error 插槽。

#error 插槽会接收 error作为参数,(如果你设置error=null,这将会触发默认插槽重新渲染,你首先需要确保错误已经完全解决,否则error插槽会二次被渲染。)

如果你跳转到其他路由,错误会自动清除。

例子

<template>
  <!-- some content -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- You use the default slot to render your content -->
    <template #error="{ error }">
      You can display the error locally here.
      <button @click="error = null">
        This will clear the error.
      </button>
    </template>
  </NuxtErrorBoundary>
</template>

参考资料

[1]

Vue ref: https://vuejs.org/api/reactivity-core.html#ref

[2]

onErrorCaptured: https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured

分类:

前端

标签:

JavaScript

作者介绍

choukin
V1