こんにちは!株式会社プロットハブのエンジニア小野です。
今回はNuxt3でcomposableを作った際にネストされると自動インポートがうまくいかない問題について解決方法を共有します。
現在のディレクトリ構成
作成してcomposablesを追加しただけの標準的なNuxt3のディレクトリ構成です。
├── app.vue
├── composables
│ ├── useTest.ts
│ └── user
│ └── useUser.ts
├── nuxt.config.ts
├── package.json
├── pages
├── public
├── server
└── tsconfig.json
composableとは
Vue3のComposition APIを使って、ロジックを再利用するための関数をまとめたものです。
UIとロジックを分離することで、コードの再利用性を高めることができます。
以下のように作成してコンポーネントなどで使用します。
composables直下にあるファイルは自動でインポートされるため、useTest
をインポートする際にuseTest
のファイル名を指定する必要はありません。
composables/useTest.ts:
export function useTest() {
const test = ref('testです')
return {
test,
}
}
pages/index.vue:
<script lang="ts" setup>
const { test } = useTest()
</script>
<template>
<div class="">
<h1>Test</h1>
<p>{{ test }}</p>
</div>
</template>
以下のようにcomposables/useTest.ts
に作成した「testです」を返す関数を作成し、pages/index.vue
で使用しています。
ネストされたcomposableを作成
composables/user/useUser.tsを作成し、以下のようにuser1
を返す関数を作成します。
import { ref } from 'vue'
export function useUser() {
const user = ref('user1')
return {
user,
}
}
pages/index.vueに以下のようにuseUser
をインポートして使用するとどうなるでしょうか。
<script lang="ts" setup>
const { test } = useTest()
const { user } = useUser()
</script>
<template>
<div class="">
<h1>Test</h1>
<p>{{ test }}</p>
<h1>User</h1>
<p>{{ user }}</p>
</div>
</template>
500エラーになり「useUser is not defined」と表示されます。
composableはディレクトリ直下にあるファイルのみが自動でインポートされるため、ネストされたcomposableは自動でインポートされないためエラーが発生します。
ファイルのスキャン方法
使用するファイルでimportする
使用したいファイルでimportするという方法があります。
以下を追加すると読みこまれるためエラーが解消されます。
import { useUser } from "~/composables/user/useUser";
pages/index.vue:
<script lang="ts" setup>
import { useUser } from "~/composables/user/useUser";
const { test } = useTest()
const { user } = useUser()
</script>
<template>
<div class="">
<h1>Test</h1>
<p>{{ test }}</p>
<h1>User</h1>
<p>{{ user }}</p>
</div>
</template>
これでエラーが解消され、正常に表示されるようになりますが使用する箇所で毎回importする必要があるため、コードが冗長になります。
composables/index.tsを作成
composables/index.tsを作成し、以下のようにネストされたcomposableをインポートする方法もあります。
composables/index.ts:
export { useUser } from './user/useUser'
Nuxt3はcomposables直下のファイルを自動でインポートするため、composables/index.tsを作成し、ネストされたcomposableをインポートすることでエラーが解消されます。
これはcomposables直下のファイルを自動でインポートする仕組みを利用しています。
pages/imdex.vue:
<script lang="ts" setup>
const { test } = useTest()
const { user } = useUser()
</script>
<template>
<div class="">
<h1>Test</h1>
<p>{{ test }}</p>
<h1>User</h1>
<p>{{ user }}</p>
</div>
</template>
nuxt.config.tsに設定
nuxt.config.tsに以下の設定を追加することで、composables直下のファイル以外も自動でインポートされるようになります。
公式サイトにも記載されている内容でnuxt.config.tsに記載するだけで全てのcomposableを自動でインポートすることができます。
export default defineNuxtConfig({
imports: {
dirs: [
'composables',
'composables/*/index.{ts,js,mjs,mts}',
'composables/**'
]
}
})
結果
どの方法を選択してもエラーが解消され、正常に表示されるようになります。
まとめ
Nuxt3でcomposableを作成する際にネストされると自動でインポートされない問題について解決方法を共有しました。
個人的にはnuxt.config.tsに設定を追加する方法が一番スマートだと思いますが知らないとimportして実装してしまう可能性があるのでドキュメントを作成ししっかりとルールを決めておく必要があると感じました。
コメント