NUXT・直観的なWEBフレームワーク
はじめに
Nuxtは、Vue.jsに基づく公開ソースのJavaScriptフレームワークの一つです。現時点で最新バージョンはNuxt 3です。Nuxt 3はVite、Vue 3とNitroに基づき、TypescriptのサポートでNuxtフレームワークからアップグレードされたバージョンです。
Nuxtは、CSR、ISR、ESR、SWRといった方法に加えてサーバーサイドレンダリングというServer Side Rendering(SSRと略す)と静的サイトジェネレーターというStatic Site Generator(SSGと略す)の方法でウェブアプリケーションの開発を簡素化できます。Nuxt は、Vue.jsアプリケーションを構築するため規約ベースで構成されたアプローチの手段を提供し、開発者が複雑な構成を処理する代わりにに機能の開発に集中できるようにします。
どうしてNuxtを使うか
サーバーサイドレンダリング (SSR):Nuxtはサーバーサイドレンダリングを活用しています。つまり、Vue.jsのコンポーネントは、クライアントに送信される前にサーバーで事前にレンダリングされるということです。これにより、検索エンジンがレンダリングされた内容にインデックスを付けることのできっるため、ページ初期化のパフォーマンスが向上され、検索エンジン最適化(SEO)が可能となります。
静的サイトジェネレーター (SSG): Nuxtは、ビルド時に静的なHTMLファイルを生成でき、直接に、CDNまたは静的ホスティングサービスから提供されます。このアプローチにより、リクエストごとのサーバーサイドレンダリングの必要性を無くして、ページの読み込みが高速となり、拡張性が向上されます。
レンダリング高速化:Vueの仮想DOM(VDOM)はゼロから書き直され、レンダリングパフォーマンスが向上されました。また、コンパイルされたシングルファイルコンポーネントというSingle-File Component(SFCと略す) と操作する場合、Vueのコンパイラーはビルド時に静的マークアップと動的マークアップに分離することで、コンポーネントをさらに最適化できます。これにより、最初のレンダリング(コンポーネントの生成)および更新が迅速に行われ、メモリの使用量が削減されます。Nuxt 3では、サーバーサイドレンダリングも高速化されます。
バンドル縮小化:Vue 3とNuxt 3では、バンドルサイズの削減に焦点を当てています。Tree-shakingというツリーシェイク手法を実装することで、アプリケーションの本番環境においては、バンドル時、使わないコンポーネントとテンプレート・ディレクティブといったVueの機能を除外します。これにより、ファイルサイズが削減されて、ダウンロードが高速化され、アプリケーションの読み込み時間も短縮できます。この方法では、Vue 3のアプリケーションはgzipで圧縮すると、少なくとも12 kbに縮小できます。
エコシステム広範化:Nuxtはコミュニティによって貢献された多様な開発エコシステムを持っています。コミュニティのプラグイン、モジュール、ツールを利用して、自分のアプリケーションを拡張し、カスタマイズすることができます。
タイプスクリプトのサポート: Nuxt 2は、既にタイプスクリプトをサポートしていましたが、Nuxt 3ではタイプスクリプトのサポートが更に強化されており、Nuxt が Typescript に基づいて提供するType-checking機能やその他のツールを利用できます。
開発の簡素化: Nuxtは、コンベンションオーバーコンフィグレーションという設定より規約により、定型コードを削減して開発プロセスを簡素化します。ルーティング、コード分割、状態管理などの機能が組み込まれたので、設定や構成について心配することなくアプリケーションロジックの構築に集中できます。
良い開発者体験:Nuxtは、ホットモジュールリプレイスメント、動リロード、エラーハンドリング等の機能や、デバッグ、テスト、開発のための革新的なツールや他のツールを備えた堅牢な開発環境を提供します。これらの機能によって開発プロセスが合理化されており、繰り返しがより速くなり、デバッグの可能性がより良くなります。
拡張性とパフォーマンス:Nuxtは、自動コード分割、レイジーロード、プレレンダリングといった各機能を通じて、アプリケーションのパフォーマンスを最適化します。これにより、必要なJavaScriptのみが各ページにロードされるので、読み込み時間が速くなり、ユーザー体験が向上されます。また、Nuxtのモジュラー型アーキテクチャでは、アプリケーションのバージョンをアップグレードする時に易く拡張する可能性があります。
サポート中の技術
各機能の比較
以下に、Nuxtの3つのバージョン間の比較表を示します。
ディレクトリ構造
.nuxt:Nuxtは、開発中に「.nuxt/」ディレクトリを使用して Vueアプリケーションを作成します。
.output:Nuxtは、本番環境でアプリケーションをビルドする時に「.output/」ディレクトリを作成します。
assets:「assets/」ディレクトリは、ビルドツール(webpackまたはVite)が処理するウェブサイトのすべてのコンテンツを追加するために使われます。通常、このディレクトリには、スタイルシート(CSS、SASSなど)、フォント、 「public/」ディレクトリから提供されない画像といったファイルが格納されます。
components:「components/」ディレクトリは、すべてのVueコンポーネントを格納する置き場です。そこからは、ページや他のコンポーネント内にインポートすることができます。
composables:Nuxt 3では、自動インポート機能を使うことで「composables/」ディレクトリを利用してVueコンポーザブルを自動的にアプリケーションにインポートします。
content:アプリケーションのCMSを作成するため、.md、.yml、.csvのファイルフォーマットをサポートします。
layouts:アプリケーションの見た目を変更するために使われます。アプリケーションには、管理者用レイアウト、ゲスト用レイアウト、登録済みクライアント用レイアウトといったレイアウトが複数あり得ます。これらのレイアウトは、異なるページに流用されて、見た目(サイドバー、メニュー、フッター等)を処理します。インストール時に、Nuxt CLI はデフォルトとしてlayouts/default.vueレイアウトを設定してすべてのページに適用されます。
middleware:ページを表示させる前にリクエストを処理するために使われます。Middlewareを利用することにより、ページが表示される前に認証、アクセス権限チェック、動作ログ出力、その他のカスタム処理などのタスクを実行することができます。
modules:Nuxtは、開始する前に「modules/」ディレクトリをスキャンして、ロードします。それは、アプリケーションを構築する時に開発したローカルモジュールを配置するのに適した場所です。
node_modules:パッケージマネージャ(npm、yarn若しくはpnpm)は、プロジェクトの依存関係を保存するため「node_modules/」ディレクトリを作成します。
pages:Nuxtは、ファイルに基づくルーティングを提供し、ウェブアプリケーション内のルートをVue Routerで作成します。
plugins:Nuxtは、自動的に「plugins/」ディレクトリ内のファイルを読み取って、Vueアプリケーション作成時にそれらをロードします。ファイル名にある「.server」か「.client」という接尾辞を使って、プラグインをサーバー或いはクライアントにのみロードすることができます。
public:「public/」ディレクトリには、静的ファイルが含まれており、HTTPリクエストに対して追加のロジック処理なしでリソースを直接提供します。例えば、画像ファイル、フォント、robot.txt、favicon.ico、静的ファイルを配置できます。
server:Nuxtは、「~/server/api」、「~/server/routes」、「~/server/middleware」の各ディレクトリのファイルを自動的にスキャンしてAPIハンドラーとサーバーハンドラーをHMRのサポートで登録します。
utils:Nuxt 3は、auto-imports機能を使うことで「utils/」ディレクトリを利用してヘルパー機能やその他のユーティリティをアプリケーションに自動的にインポートします。
.env:Nuxt CLIは、開発モードおよびnuxi build
やnuxi generate
実行時で組み込まれたdotenvをサポートします。プロセスの環境変数の他に、プロジェクトのルートディレクトリに.env ファイルが存在する場合、そのファイルはビルド時や開発時や生成時に自動的にロードされます。また、そこに設定されている環境変数は モジュールやnuxt.configファイルでアクセスできます。
.gitignore:Gitとの操作する度にパースされたくないプロジェクト内のファイルやフォルダの名前をリストアップすることに使われます。
.nuxtignore:Nuxt は.nuxtignoreファイルを使うと、ビルド中にプロジェクトのルートディレクトリ(rootDir)内のレイアウト、ページ、コンポーネント、コンポーザブル、ミドルウェアを無視することができます。.nuxtignoreファイルは.gitignoreファイルや.eslintignoreファイルと同じ仕様に従い、各行がどのファイルを無視するかのことを示すグロブパターンです。
app.config.ts:Nuxtアプリケーションの構成とカスタマイズに使われます。
app.vue:Nuxt 3アプリケーションの主要コンポーネントです。
nuxt.config.ts:nuxt.config.tsファイルには、Nuxtのカスタマイズ構成が含まれており、アプリケーションの構成を行うことができます。これらの構成には、ヘッド タイトル、関連スタイル、スクリプト、ミドルウェア、プラグイン、認証、モジュール、さらにAPIが含まれます。
package.json:アプリケーションのすべての依存関係とスクリプトが含まれます。
tsconfig.json:Nuxtは、他の適切なデフォルト値を.nuxt/tsconfig.jsonファイルを自動的に生成します。ですので、ルートの外にtsconfig.jsonファイルを作成して、初期化されたNuxtファイルからインポートするだけで済みます。
機能
Auto-imports
自動取り込みというAuto-importsは、Nuxt 3で開発された新しい機能であり、非常に便利です。コンポーネント、コンポーザブル、ユーティリティ内のすべてのファイルは自動的に認識され、再度インポートすることなく、コンポーネント、コンポーザブルなどに名前を付けるだけで済みます。Auto-importsはデフォルトとして有効になっていますが、nuxt.config.tsファイルで以下のように無効にすることもできます。
export default defineNuxtConfig({ imports: { autoImport: false } })
Rendering Modes
Nuxtは、ユニバーサル レンダリング、クライアントサイドレンダリングといった様々なレンダリング モードをサポートしていますが、ハイブリッド レンダリングを提供して、CDNエッジサーバー上でアプリケーションをレンダリングすることができます。
Server Engine
Nuxt 3は新しいサーバーエンジンであるNitroを搭載しています。
- Node.js、ブラウザ、サービスワーカー等のクロスプラットフォームのサポート
- 直ぐに使えるサーバーレスのサポート
- APIルートのサポート
- 自動コード分割と非同期ロードされたかたまりの自動化
- 静的ページとサーバーレスページのハイブリッドモード
- ホットモジュールリロードを使った開発サーバー
Nuxt開始
前提条件:Nodejsバージョン 16.0.0以降
Nuxt CLIを使用した簡単な設定をnuxi
コマンドと一緒に使うと、すべてのNuxtコンポーネントをインストールし、管理することができます。 npxがインストールされたら、下記のコマンドで簡単にプロジェクトを作成できます。
> npx nuxi init project-name
結果は以下のようになります。
Nuxt project is created with v3 template. Next steps: › cd project-name › Install dependencies with npm install or yarn install or pnpm install › Start development server with npm run dev or yarn dev or pnpm run dev
下記のコマンドで依存関係をインストールします。
yarn install
そして、新しいプロジェクト構造は以下のようになります。
これで、Nuxt アプリケーションを開発モードで起動できるようになります。
yarn dev -o
次に、ブラウザ(http://localhost:3000/)にアクセスして、作成したてのNuxtアプリケーションが動いていることを確認できます。
デフォルトとしては、app .vueファイルは、エントリポイントとしての役割を果たすコア コンポーネントであり、各アプリケーション ルートに対しコンテンツをレンダリングする。このファイルもNuxtアプリケーションのルートコンポーネントであり、他のすべてのコンポーネントを包括するレイアウトと構造を表します。通常、メイン レイアウト、ナビゲーション、および複数のページ間で共用する必要があるグローバルコンポーネントやロジックが含まれます。
では、app.vueファイルの内容を少し変更して、表示を確認してみてください。
> app.vue <template> <div> <h1>Welcome to the homepage</h1> <div> </template>
特徴
Pages
これは、アプリケーションビューとルートが配置される場所です。デフォルトとして、Nuxtは各ファイルに基づくルーティングシステムを使用し、「pages/」ディレクトリ内の.vueファイルの一つずつは一つのルートに該当します。
Pagesを使うためには、pages/index.vueファイルを作成し、<NuxtPage/>コンポーネントをapp.vueに追加します(若しくは、pages/index.vueをデフォルトにしたい場合、app.vueを削除します)。Pagesは、Vueコンポーネントであり、Nuxtのサポートする有効な拡張子 (デフォルトでは、.vue、.js、.jsx、.mjs、.ts、または.tsx)を持つことができます。Nuxtは、「~/pages/」ディレクトリ内のすべてのページに対しルートを自動的に生成します。
> app.vue (app.vueをデフォルトにした場合) <template> <NuxtPage /> </template> --- .vue --- > pages/index.vue <template> <p>Home Page</p> </template> > pages/about.vue <template> <p>About Page</p> </template> --- .ts --- > pages/index.ts export default defineComponent({ render () { return h('h1', 'Home page'); } }); --- .tsx --- export default defineComponent({ render () { return <h1>Home page</h1>; } });
Layouts
Layoutは、アプリケーション内の各ページの全体的なデザインと構造を決定する上で重要な役割を果たします。NuxtのLayoutは、ページコンポーネントに再利用可能なテンプレートを表し、複数のページで統一的な見た目を提供します。また、ログインページのレイアウト、ホームページのレイアウト、他のレイアウト等の異なるレイアウトを作成することもできます。
もしアプリケーションにレイアウトが1 つしかない場合、app.vueを<NuxtPage />コンポーネントと共に使用することをお勧めします。
何も設定しない場合、Nuxtは、default.vueをデフォルトとして指定します。
> app.vue <template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template> > layouts/default.vue <template> <div> <h1>This our default layout</h1> <slot /> </div> </template> > pages/index.vue <template> <p>Home Page</p> </template>
では、もっと面白いことをやってみましょう。カスタムレイアウトを作成して、そのレイアウトで「/About」ページを表示してみましょう。
> layouts/custom.vue <template> <div> <h1>This our custom layout</h1> <slot /> </div> </template> > pages/about.vue <template> <p>About Page</p> </template> <script setup> definePageMeta({ layout: 'custom', }); </script>
Routing
動的ルート
では、Nuxt ファイルに基づくルーティングを使ってルートを作成する様々な方法を見てみましょう。
以下の例では、「~/pages/」ディレクトリの構造を見てみましょう。内容がルートパラメータに基づいて可変する動的ページと静的ページの2種類のページがあります。
- 静的ページ
- index.vue → /
- about.vue → /about
- category/index.vue → /category
- 動的ページ
- category/[slug].vue → /category/language
- user-[group]/[id].vue → /user-admin/123
> pages/category/[slug].vue <template> <p>Category slug : {{ $route.params.slug }}</p> </template> <script setup> const route = useRoute(); useHead({ title: `Category ${route.params.slug}` }); </script>
> pages/user-[group]/[id].vue <template> <p>Group : {{ $route.params.group }} - ID : {{ $route.params.id }}</p> </template> <script setup> const route = useRoute(); useHead({ title: `User group ${route.params.group} ID ${route.params.id}` }); </script>
ネストルート
これは、親ルートが子ルートまたはサブルートを持つ階層型で表示されるページの構造です。各ページが共通レイアアウトを共用し、または、アプリケーション内でのルートをネストするよう整理したい場合に役に立ちます。<NuxtPage> を使用してネストされたルートを表示することができます。
このファイルツリーは次のようなルートを生成します。
[ { path: '/user', component: '~/pages/user.vue', name: 'user', children: [ { path: '/', component: '~/pages/user/index.vue', name: 'user-child' }, { path: '/:id', component: '~/pages/user/[id].vue', name: 'user-id', children: [ { path: '/profile', component: '~/pages/user/[id]/profile.vue', name: 'user-id-profile' }, { path: '/division', component: '~/pages/user/[id]/division/index.vue', name: 'user-id-division', children: [ { path: '/:division/:divisionId', component: '~/pages/user/[id]/division/[division]/[divisionId].vue', name: 'user-id-division-id' } ] }, ] } ] } ]
ユーザールートと子ルートの結果は以下になります。
> pages/user.vue <template> <p>User Page</p> <NuxtPage /> </template> > pages/user/index.vue <template> <p>User Child Page</p> </template>
ユーザープロフィールルートとユーザーIDのパラメーターの結果は以下になります。
> pages/user.vue (parent route) > pages/user/[id]/profile <template> <p>User Profile Page - User ID : {{ $route.params.id }}</p> </template>
ユーザーディビジョンルートとユーザーIDのパラメーターの結果は以下になります。
> pages/user.vue (parent route) > pages/user/[id]/division/index.vue <template> <p>User ID : {{ $route.params.id }}</p> <p>User division : {{ $route.params.division }}</p> </template>
ユーザーディビジョンルートとユーザーIDとディビジョンIDのパラメーターの結果は以下になります。
> pages/user.vue (parent route) > pages/user/[id]/division/[division]/[divisionId].vue <template> <p>User ID : {{ $route.params.id }}</p> <p>User division : {{ $route.params.division }} - Division ID : {{ $route.params.divisionId }}</p> </template>
ナビゲーション
これは、アプリケーション内の異なるページまたはルート間を遷移するプロセスです。 Nuxtは、<NuxtLink>コンポーネントを使って、href 属性を持つ <a> タグをレンダリングしてページのルートを設定することでページを連結します。
> pages/index.vue <template> <div> <p>Home Page</p> <nav> <ul> <li><NuxtLink to="/about">About</NuxtLink></li> <li><NuxtLink to="/category">Category</NuxtLink></li> <li><NuxtLink to="/user">User</NuxtLink></li> </ul> </nav> </div> </template> <style scoped> a { text-decoration: none; line-height: 1.5em; color: #0e0d0d; font-weight: 600; } </style>
「About」、「Category」、「User」の各リンクをクリックすると、それぞれで該当ページにリダイレクトします。
<NuxtLink>コンポーネントを、以下の二つのオブジェクトを持つパラメーターProps「to」と使います。
- name:ページ名であり、該当するルートでもある。例:pages/category/[slug].vue → /category/:slug ⇒ 子フォルダー間に「-」を入れる形で命名するので、category-slugになる。
- params:動的ルートを使用する場合の引渡すパラメーター
> pages/category/index.vue <template> <p>Category Page</p> <nav> <ul v-for="(cate, index) in categories" :key="index"> <li> <NuxtLink :to="{ name: 'category-slug', params: { slug: cate } }"> {{ cate }} </NuxtLink> </li> </ul> </nav> </template> <script setup> const categories = ['language', 'reading', 'programming', 'art', 'other']; </script> <style scoped> a { text-decoration: none; line-height: 1.5em; color: #0e0d0d; font-weight: 600; } </style>
アセット
- 「public/」ディレクトリの内容はサーバールートで提供されます。
- 「assets/」ディレクトリには、ビルドツール(Viteまたはwebpack)の処理するすべてのコンテンツが含まれています。
「public/」ディレクトリ
例えば、「public/img/」ディレクトリにある画像ファイルに関連して、静的なURL「/img/nuxt.png」が利用可能です。
<template> <img src="/img/nuxt.png" alt="Discover Nuxt 3" /> </template>
「assets/」ディレクトリ
Nuxtは「/assets/my-file.png」等の静的URLで「assets/」ディレクトリ内のファイルを提供しません。静的URLが必要な場合は、「public/」ディレクトリを使用してください。
スタイルシートファイル(CSS、SASSなど)、フォント、またはSVGファイルを設定することができます。グローバルコマンドをNuxtコンポーネントに挿入するには、nuxt.configファイルのViteオプションを使えます。
以下の例を見てください。
> assets/css/styles.css a { text-decoration: none; line-height: 1.5em; color: #0e0d0d; font-weight: 600; } > assets/sass/_colors.scss $primary: #49240F; $secondary: #E4A79D; > assets/sass/app.scss @import url("https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap"); body { font-family: 'Nunito', } .btn-bg-color { background-color: $primary; } > nuxt.config.ts export default defineNuxtConfig({ css: [ '~/assets/css/styles.css', '~/assets/sass/app.scss', ], vite: { css: { preprocessorOptions: { scss: { additionalData: '@use "@/assets/sass/_colors.scss" as *;' } } } } })
コンポーネント
「components/」フォルダは、ページや他のコンポーネントに取り込まれる全てのVueコンポーネントを配置する場所です。
Nuxtは、「components/」ディレクトリ内のコンポーネント(使用しているモジュールによって登録されているコンポーネントも含め)を自動的にインポートします。
さらに、Nuxtには< ClientOnly >、< NuxtPage >、< NuxtLayout >、< NuxtLink >、< Teleport >などの組み込みコンポーネントもあります。
> components --| BaseHeader.vue --| BaseFooter.vue --| base/ ----| html/ ------| Alert.vue > layouts/default.vue <template> <div> <BaseHeader /> <BaseHtmlAlert /> <slot /> <BaseFooter /> </div> </template>
コンポーザブル
NuxtはuseAppConfig、useAsyncData、useCookie、useError、useFetch、useHeadなどのコンポーザブルを提供します。また、Nuxtは自動インポート機能を使って「composables」ディレクトリ内のファイルを自動的にインポートします。
プラグイン
Nuxt は、「plugins」ディレクトリ内のファイルを自動的に読み取り、Vue アプリケーションの作成時にそれらをロードします。ファイル名に .server か.clientという接尾辞を使用すると、サーバー側またはクライアント側にのみプラグインをロードできます。
「plugins/」ディレクトリ内のすべてのプラグインは自動的に登録されるため、nuxt.config に個別に追加する必要はありません。
モジュール
Nuxtは、コミュニティの開発したモジュールのリストを提供します。これにより、アプリケーションを開発する時の選択肢が多くなります。
アプリケーションに必要なモジュールをインストールし、nuxt.config.tsファイルで構成を設定します。
export default defineNuxtConfig({ modules: [ '@vueuse/nuxt', '@element-plus/nuxt', 'nuxt-lodash', 'nuxt-security', ] })
Nuxtは、カスタムファイルについて開始前に「modules/」ディレクトリをスキャンしてロードします。アプリケーション構築中に開発したローカルモジュールを配置するのに適した場所です。
modules/*/*.ts modules/*.ts
データフェッチング
Nuxt 3では、useFetch、useLazyFetch、useAsyncData、useLazyAsyncData、$fetch などのブラウザまたはサーバーからデータをフェッチするためのコンポーザブルと組み込みライブラリが殆どサポートされます。
useFetch
useFetchは、サーバー側(Nuxtのサーバーサイドレンダリングモードで)でレンダリングされ、Nuxtアプリケーションにデータをロードするために使われます。 useFetchは、ページ、コンポーネント、またはプラグインにも使えます。useFetchの使用方法は以下のように非常に簡単です。
<template> <div> Page visits: {{ count }} </div> </template> <script setup> const { data: count } = await useFetch('/api/count'); </script>
オプション
- method:リクエストのメソッド
- query:リクエストへのクエリ追加
- params:クエリの別名
- body:リクエストボディ
- headers:リクエストヘッダ
- baseURL:ベースURL
- key:キャッシュに保持するデータとリクエストの動作をコントロールする一意の値
- server:サーバー上のデータフェッチの有無(デフォルトはtrue)
- default:対象のデフォルト値指定
- pick:対象データからのプロパティー抽出
- watch:対象の変更をヒアリングしてのuseFetch再度呼出
- transform:出力変換のため使用
- immediate:falseに設定すると、useFetchを直ちにトリガーしなくなる(デフォルトはtrue)
戻り値
- data:useFetchのAPIから呼び出したデータ
- pending:useFetchが引き続き呼び出されるかどうかの状態(true/false)
- refresh/execute:useFetchの外部で呼び出てデータをフェッチし直す関数
- error:API呼び出えらー時のオブジェクトエラー
以下に、上記のオプションを使用した例を示します。
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains',{ pick: ['title'], query: { param1, param2: 'value2' } }) const refreshData = () => refresh();
この使用方法は、「https://api.nuxtjs.dev/mountains?param1=value1¶m2=value2」というURLから返される配列の要素のタイトルを返却し、refreshData関数でuseFetchを再度呼び出すことができます。
useAsyncData
useFetchでは、useFetchに引渡す長いURLが多くの場所に使用される場合、管理しにくくなります。通常はAPIディレクトリを作成し、そのディレクトリ内のファイルへの API呼出関数を作成してコンポーネントまたはページにインポートします。このやり方では、useFetchを利用できないので、代わりに、useFetchとほぼ同じuseAsyncDataを使います。
<template> <div> Page visits: {{ data }} </div> </template> <script setup> const { data } = await useAsyncData('count', () => $fetch('/api/count')); </script>
例えば、以下の関数があります。
export const getPosts = () => axios.get('/api/posts');
useAsyncDataを利用するには、次のように変更します。
const { data } = await useAsyncData('projectSearch', () => getPosts());
UseAsyncDataのオプションと戻り値はuseFetchと同じですが、useAsyncDataかuseFetchを使っても、キーを追加し、ページを切り替える時にuseAsyncDataまたはuseFetchを再度コールしたい場合にclearNuxtDataを実施する必要があります。 以下にその例を示します。
<script setup> await clearNuxtData('count'); const { data } = await useAsyncData('count', () => $fetch('/api/count')); </script>
useLazyFetch
useLazyFetchの実装仕方はuseFetchと同じ、基本的にlazyオプションがtrueと指定されたuseFetchのことです。Lazyでは、データを非同期で読み取り、Nuxtは、後ろのコードと並行してデータをロードします。 それに対して、useFetchでは、データのロードが終わったら後ろのコードを実行します。また、pendingプロパティを使うことで、データのロードが終わったかどうかを判断できます。 データのロードが終わらない時、pending = trueとなり、それ以外はpending = trueとなります。
<template> <div> Page visits: {{ count }} </div> </template> <script setup> const { pending, data: count } = await useLazyFetch('/api/count'); </script>
useLazyAsyncData
useLazyAsyncDataはlazyオプションがtrueと指定されたuseAsyncDataのことです。実装方法はuseAsyncDataと同様です。
const { pending, data: post } = await useLazyAsyncData('post', () => getPosts());
$fetch
Nuxtは、ofetchを使って、グローバルな可視性を$fetchヘルパーで実現して、VueアプリケーションまたはAPIルートのHTTPリクエストを作成します。
コンポーネントのデータをフェッチする時にデータを二重フェッチすることを防ぐために、useFetchまたはuseAsyncData を$fetchと一緒に使う必要があります。
<script setup> // SSR中に、データはサーバーとクライアントの両方でフェッチされて二重フェッチとなります。 const dataTwice = await $fetch('/api/item') // SSR中に、データはサーバーでフェッチされてから、クライアントへ送信されます。 const { data } = await useAsyncData('item', () => $fetch('/api/item')) // useFetchはuseAsyncDataと$fetchのショートカットとして使用できます。 const { data } = await useFetch('/api/item') </script>
$fetchは、クライアント側でのみ実行される任意のメソッドに使用できます。
<template> <button @click="contactForm">Contact</button> </template> <script setup> function contactForm() { $fetch('/api/contact', { method: 'POST', body: { hello: 'world '} }) } </script>
Server
Nuxtは、「~/server/api」、「~/server/routes」、「~/server/middleware」の各ディレクトリのファイルを自動的にスキャンしてAPIハンドラーとサーバーハンドラーをHMRのサポートで登録します。
例:/server/api/hello.tsで/api/helloルートを作成します。
> server/api/hello.ts export default defineEventHandler((event) => { return { hello: 'world' } }) > pages/hello.vue <template> <pre>{{ data }}</pre> </template> <script setup> const { data } = await useFetch('/api/hello'); </script>
処理するファイル名には、リクエストのHTTPメソッドに一致するように .get、.post、.put、.deleteといった接尾辞を付けることができます。
> server/api/test.get.ts export default defineEventHandler(() => 'Test get handler') > server/api/test.post.ts export default defineEventHandler(() => 'Test post handler')
Bodyを使ったリクエストを処理します。
> server/api/submit.post.ts export default defineEventHandler(async (event) => { const body = await readBody(event) return { body } })
クエリを使ったリクエストを処理します。
> server/api/search.ts // クエリテンプレート: /api/search?param1=a¶m2=b export default defineEventHandler((event) => { const query = getQuery(event) return { a: query.param1, b: query.param2 } })
結論
Nuxtの新しいバージョンに加えて、Vue.jsコミュニティが成長していることと Vue.jsおよびNuxtを使うコミュニティが中核技術の強みに魅了されたことにより、豊富で多様な参考資料が出現します。
メリット
- パフォーマンス向上
- モバイルアプリケーションのパフォーマンス改善
- 柔軟なモジュラー型アーキテクチャ
- Typescript、プラグイン、デバッグツールのサポート強化
- SEO最適化
- Vue 3との統合化
- 複雑な設定の削減
デメリット
- 初心者の場合、Vue.js基礎知識を身につけること
- Nuxtの標準のフォルダ構造に従えることによって、フォルダ構造をカスタマイズしたり、外部ツールやライブラリと統合する時に困ること
- Vue.jsのライブラリやプラグインの一部がNuxtとの互換性がなくて、追加設定が必要になること
- Nuxtが複雑なアプリケーションの開発に適した強力なフレームワークなので、簡単なプロジェクトや単一ページアプリケーションの開発に使うと、煩雑になりコストを費やすこと
- コミュニティが小さくて成長していくこと
他の流行っているレンダリングフレームワークとの比較統計↓