今回達成すること
Nuxtのinject機能を使用して、アプリ全体で使用できる共通エラー処理メソッドを作成します。
Nuxtのinjectとは
アプリ全体で関数や値を利用したい場合に、これら共通の処理をVueインスタンスに挿入する機能です。
inject('呼び出し名', <共通の値>)
Vueインスタンスに挿入することで、アプリのどこからでも呼び出せるようになります。
呼び出し時は'呼び出し名'
のキーに $
をつけて呼び出します。
inject宣言
export default (_context, inject) => {
const hoge = 'hogehoge'
inject('foo', hoge)
}
Vueインスタンスの呼び出し
console.log(this.$foo.hoge)
=> hogehoge
今回は、inject()
の第二引数にクラスを渡し、そのクラス内にアプリ全体で使用する関数を用意します。
pluginファイルを作成する
inject()
を宣言する場所は、pluginsディレクトリ内のjs
(or ts
)ファイルです。
今回は
% touch plugins/my-plugin.ts
作成したファイルは以下の編集を行います。
plugins/my-plugin.ts
// Plugin Doc: https://typescript.nuxtjs.org/cookbook/plugins/
import { Plugin, Context } from '@nuxt/types'
export interface MyPluginInterface {
}
class MyPlugin implements MyPluginInterface {
error
constructor (ctx: Context) {
this.error = ctx.error
}
}
const myPlugin: Plugin = (context: Context, inject) => {
inject('my', new MyPlugin(context))
}
export default myPlugin
import { Plugin, Context } from '@nuxt/types'
... pluginファイルのエクスポートはPlugin
の型をインポートする。MyPluginInterface
... クラスに当てがうインターフェースの宣言。class MyPlugin implements
... クラスにインターフェースを宣言する場合はimplements
を使用する。error
...constructor()
内でthis.error
を使用するため、先に宣言する必要がある。this.error = ctx.error
... Nuxtが用意しているコンテキストからerror
メソッドを代入している。
injectにクラスを渡す
inject
の第二引数で、クラスをnew
することによってそのクラス内の関数や定数を使用できるようになります。
ちなみにこのMyPlugin
クラスは、Nuxt上で$my
で呼び出すことができます。
inject('my', new MyPlugin(context))
共通エラー処理メソッドを作成する
宣言したMyPlugin
クラスに、エラー処理を行うメソッドを作成します。
plugins/my-plugin.ts
export interface MyPluginInterface {
// 追加
errorHandler (statusCode: number): void
errorMessage (statusCode: number): string
}
class MyPlugin implements MyPluginInterface {
error
constructor (ctx: Context) {
this.error = ctx.error
}
// 以下、追加
// 引数のエラーコードのエラーを発生させる
errorHandler (statusCode: number) {
this.error({
statusCode,
message: this.errorMessage(statusCode)
})
}
// 引数のエラーコードによってエラーメッセージを切り替える
errorMessage (statusCode: number) {
switch (statusCode) {
/* ここに出力したいメッセージを追加する */
case 404: return 'This page could not be found'
case 500: return 'Server error'
default: return 'Error'
}
}
}
Nuxtにpluginファイルを登録する
nuxt.config.js
export default {
...
plugins: [
'~/plugins/vuetify',
// 追加
'~/plugins/my-plugin'
],
}
以上でMyPlugin
クラスをどこからでも呼び出せるようになりました。
@nuxt/typesにMyPluginクラスの型を追加する
現状のままMyPlugin
クラスを呼び出すと、タイプエラーになります。
そこで、
- Vueの型定義を行なっている
vue/types
と、 - Nuxtの型定義を行なっている
@nuxt/types
に
MyPlugin
クラスの型を登録します。
types/module.d.ts
import { accessorType } from '~/store'
// 追加
import { MyPluginInterface } from '~/plugins/my-plugin'
declare module 'vue/types/vue' {
// Vueインスタンス(this)の型追加
interface Vue {
// nuxt-typed-vuex
// Doc: https://typed-vuex.roe.dev/getting-started/getting-started-nuxt#creating-type-definitions
$accessor: typeof accessorType
// 追加
// plugins/my-plugin.ts
$my: MyPluginInterface
}
}
declare module '@nuxt/types' {
// 追加
// Nuxt Contextへの型追加
interface Context {
// plugins/my-plugin.ts
$my: MyPluginInterface
}
// NuxtAppOptions(Context.app)への型追加
interface NuxtAppOptions {
// nuxt-typed-vuex
$accessor: typeof accessorType
}
}
interface Vue
...this
以下にプロパティを追加する場合の型定義場所。(例)this.$my
interface Context
...asyncData({ $my })
などのNuxtコンテキストで呼び出す場合の型定義場所。interface NuxtAppOptions
... Nuxtコンテキストのapp
以下にプロパティを追加する場合の型定義場所。(例)app.$my
これでタイプエラーなく$my
が使用できるようになりました。
mounted (): void {
console.log(this.$my)
}
// Console
=> ▶︎ MyPlugin {error: ƒ}
今後、自作プラグインを作成する場合は、vue/types
と@nuxt/types
に型を登録することを覚えておいてください。
コンテンツページから$myを呼び出そう
$my
でMyPlugin
クラスのerrorHandler()
メソッドを呼び出しましょう。
pages/categories/_slug.vue
// コンテキストのerror削除。$my追加
asyncData ({ app: { $accessor }, params, $my }: Context): AsyncData {
const category: BlogCategory | undefined =
$accessor.categories.find((category: BlogCategory) =>
category.fields.slug === params.slug
)
if (!category) {
// 書き換え
return $my.errorHandler(404)
// return error({
// statusCode: 404,
// message: 'This page could not be found'
// })
}
const categoryPosts: BlogPost[] = $accessor.categoryPosts[category.sys.id]
return {
category,
categoryPosts
}
}
これで前回の挙動と同じく、存在しないパスにアクセスすると404エラーが発生します。
本番環境の挙動も確認してみる
ここまでの変更を本番環境にデプロイし、本番での挙動も確認してみてください。
% yarn netlify:deploy
存在しないパスにアクセスしてみましょう。
本番環境ではNetlifyが用意している404エラーページに遷移します。
Nuxtのエラーページを表示する設定はもう少し先で行います。
今回の作業は以上です。
% git add -A
% git commit -m "Add MyPlugin class to plugin file"
まとめと次回
今回は、Nuxtのinject
を使用して共通エラーメソッドを作成しました。
次回はブログ記事のコンテンツページを作成します。
CSSなどの設定は全ての機能が揃ってから設定していきます。