はじめに
Nuxt3はVue.jsベースのフレームワークで、より効率的にフロントエンド開発を行うことができます。
本フレームワークを使用する様々なメリットについて、またフロントサイドで私が良いなと感じたポイントを紹介します。
サンプルコードを交えて解説しますので、少しでもNux3を使ってみたいと思っていただければ幸いです。
(Nuxt3に関連するサービスなど、いくつか説明を省略しています。興味のある方は調べてみてください。)
こんな人に読んでほしい
- Vue.jsの経験がある
- Nuxt.jsを使ってみたい
- もっと効率的にフロントエンド開発を行いたい
- フレームワークを使ってみたい
目次
- Nuxt3とは
- 環境構築
- ディレクトリ構造について
- 主要な機能について
- 機能紹介
- まとめ
Nuxt3とは
Nuxt3はNitroを搭載したVue.js のフルスタックフレームワークです。
Vueアプリケーション開発を効率化するための多くの機能を提供します。
Nuxt2との違いについて
2022年11月16日正式リリースされたフレームワークで、Vue2からVue3ベースへアップデートされています。
以前はComposition APIを使用するため別途プラグインが必要でしたが(Nuxt2の説明は省きます)、デフォルトで使用可能になりました。
ビルドツールのViteをサポートしており、Nitroエンジンの搭載でパフォーマンスが向上しました。
さらにNuxt2ではサポートされていなかったTypeScriptをサポートしています。
環境構築
まずはサンプルコードを動かすための環境構築をしましょう。
コマンド1つで非常に簡単に構築可能です。
また、Node.js v18.0.0
以上が推奨されているため、必要であればバージョンアップしてください。
(お使いの環境により方法が異なるため、Nodeのバージョンアップ方法は省きます)
インストールしたいディレクトリに移動し、以下コマンドを実行しましょう。
好きなパッケージマネージャーを選択するよう求められるので選択し、Enterで進んでください。
私はyarn
を選択しました。
npx nuxi@latest init {project-name}
それでは必要な依存関係をインストールします。
cd {project-name}
yarn install
次に以下コマンドでアプリを起動してみましょう!
yarn dev
ブラウザのURLバーにURLを貼り付けてこのような画面が起動すれば成功です。
localhost:3000
インストール直後のディレクトリ構造はこのようになっています。
ブラウザ上に表示される内容に関わるファイルはapp.vue
ファイルのみだということがわかります。
(エディターはVSCodeで表示しています。)
ディレクトリ構造について
Nuxt3は事前に決められている名前のディレクトリを追加することでアプリケーションを構築していきます。
それぞれの名前がどのような役割を持っているかを以下にまとめました。
後ほどそれぞれサンプルコードを交えて解説していきます。
ディレクトリ名 | 役割 |
---|---|
pages | 各画面を配置 |
layouts | 共通部品を配置 |
components | コンポーネントを配置 |
composables | composableな関数(reactiveな変数とロジックをコンポーネントから切り離して再利用できるようにした関数)を含むファイルを配置 |
assets | cssファイルや画像などを配置 |
public | 画像ファイルのような静的ファイルを配置(faviconとか) assetsとの違いとして、バンドルによりビルド後に名称を変更したくないファイル(S3にアップするものなど)を配置 |
plugins | アプケーション初期化時に実行される |
middleware | Route Middlewareを利用することでページ間の移動、サイトへのアクセスをトリガーとしてページが表示される前に事前に設定していた処理を行う |
server | API Routeを作成 |
主要な機能について
Nuxt3の強みのうち、いくつかフロントサイドの機能を紹介します。
- 自動ルーティング
- 明示的にルーティングを書かなくてもやってくれる(VueRouterを使ってマッピングしている)
- ネストされたページのルーティングも可能
- 動的ルーティング
- URLの一部を動的に変更することで、一つのファイルで複数のルーティングを可能にする
- [id].vueを作成することで取得可能
- 自動インポート
- import文を書かなくてもコンポーネントを読み込んでくれる
- 共通レイアウト設定
- デフォルトと名前付きの2パターン実装可能
機能紹介
上述した各ディレクトリの使い方を、サンプルコードを交えて紹介していきます。
- pagesディレクトリ
- layoutsディレクトリ
- componentsディレクトリ
- composablesディレクトリ
- assetsディレクトリ
- publicディレクトリ
- pluginsディレクトリ
- middlewareディレクトリ
- serverディレクトリ
pagesディレクトリ
Nuxt3を使用しない場合、VueRouterを使用して明示的にルーティングをする方法が一般的かと思いますが、pagesディレクトリに配置した各画面ファイルは自動ルーティング
されます。
以下コマンドでpages/about.vue
を作成しましょう。
mkdir pages
code pages/about.vue
そして、以下内容を貼り付けてください。
<template>
<h1>About Page</h1>
</template>
URLを以下に変更してください。
localhost:3000/about
pagesディレクトリにファイルを作成するだけでルーティングしてくれるのでとても便利ですね。
では、ディレクトリがネストされている場合はどうでしょうか。
pages/user/index.vue
ファイルを作成しましよう。
mkdir pages/user
code pages/user/index.vue
同様に以下内容を貼り付けてください。
<template>
<h1>User Page</h1>
</template>
URLをネストされたディレクトリ名にしたい場合は、index.vue
というファイル名で作成しましょう。
するとディレクトリ名でルーティングされます。
localhost:3000/user
続けて、動的ルーティングしてみましょう。
userのid毎にURLを変えたい場合などに有効です。
ファイル名が少し特殊で[id].vue
のようにします。
コマンドベースで作成されない場合は手動作成してください。
<script setup>
const router = useRoute();
console.log('user id:', router.params.id);
</script>
<template>
<h1>User ID Page</h1>
<p>ページID: {{ $route.params.id }}</p>
</template>
localhost:3000/user/1
URLの末尾に付与した番号(ID)を変更してみましょう。
どの番号を付与しても画面が表示されます。これが動的ルーティングです。
また<script>
タグに以下実装をすることでパラメータとしてIDを取得することができます。
const router = useRoute();
router.params.id
layoutsディレクトリ
layoutsディレクトリは共通部品を配置します。
今回はヘッダータイトルを配置します。
layoutsディレクトリを作成しdefault.vue
を作成しましょう。
mkdir layouts
code layouts/default.vue
<template>
<div style="border-bottom: 3px solid;">
<h1 style="background-color: #B0F8FF">共通ヘッダー</h1>
<slot />
</div>
</template>
<slot />
タグをつけることを忘れないでください。
ここに他コンポーネントが展開されます。
またapp.vue
ファイルを以下に書き換えてください。
デフォルトのWelcomeページから独自で作成したページを表示するよう変更します。
<NuxtLayout>
に共通部品が展開され、また<NuxtPage />
タグにpages
ディレクトリ以下のファイルが展開されます。
<template>
<div>
<NuxtLayout></NuxtLayout>
<NuxtPage />
</div>
</template>
localhost:3000/about
、localhost:3000/user
にアクセスすると、すべてのページでヘッダータイトルが表示されることがわかります。
componentsディレクトリ
componentsディレクトリにボタンコンポーネントを配置します。
components
ディレクトリを作成し、その下にbutton.vue
を作成しましょう。
mkdir components
code components/button.vue
<template>
<button type="button" class="btn">ボタン</button>
</template>
<style>
.btn {
width: 100px;
height: 30px;
background-color: blue;
color: white;
}
</style>
それではabout.vue
でコンポーネントを読み込んでみましょう。
Nuxt3を使わない場合はインポート文を記述する必要がありますが、自動ルーティング機能により記述は不要です。明示的に記述する方法もあるので好きな方で実装してください。
about.vue
を以下のように書き換えます。
<template>
<h1>About Page</h1>
<Button />
</template>
これでボタンコンポーネントが表示可能になります。
composablesディレクトリ
composablesディレクトリの中にcomposable関数を含むファイルを配置します。
今回は、ボタンクリックをトリガーとして数値をインクリメント、デクリメントする関数を作成してみます。
composablesディレクトリを作成しuseCounter.ts
を作成しましょう。
mkdir composables
code composables/useCounter.ts
export function useCounter(initialValue: number) {
const count = ref(initialValue);
const inc = () => (count.value = count.value + 1);
const dec = () => (count.value = count.value - 1);
return {
count,
inc,
dec,
};
}
そしてabout.vue
でこの関数を読み出すため以下のように変更してください。
<script setup>
const { count, inc, dec } = useCounter(1);
</script>
<template>
<h1>About Page</h1>
<div>Count:{{ count }}</div>
<div>
<Button @click="() => inc()">increase</button>
<Button @click="() => dec()">decrease</button>
</div>
</template>
左のボタンをくりっくするとインクリメント、右のボタンをクリックするとデクリメントします。
useCounterに初期値として1
を渡し、それぞれのボタンのクリックをトリガーとしてinc
,dec
が呼び出されます。
assetsディレクトリ
assetsディレクトリは静的ファイルを配置します。
assets
ディレクトリを作成し、全体へ適用したいCSSファイルを作成しましょう。
mkdir -p assets/css
code assets/css/style.css
style.cssの中身として以下を貼り付けてください。
body {
background-color: #FFFFBB;
}
またCSSファイルを読み込ませるため、nuxt.config.ts
を以下へ書き換えてください。
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
css: [
"@/assets/css/style.css"
],
})
今回は背景へ薄い黄色を設定しました。
どのページへ移動しても背景色が設定されていることが確認できます。
publicディレクトリ
publicディレクトリはassetsディレクトリと同様静的ファイルを配置しますが、バンドルビルド後にファイル名を変更したくないファイルなどを配置します。
試しにビルドした結果を見てみましょう。
環境構築時にすでにpublic/favicon.ico
が作成されています。
それではビルドしてみましょう。
yarn build
成功すると.nuxt
, .output
ディレクトリが作成されます。
静的ファイルは.output/public
に集約されます。
.output/public/favicon.ico
が作成されていることを確認してみましょう。
今回は省きますが、assets, publicそれぞれへ配置した静的ファイルへのアクセス方法も異なるので、気になる方は調べてみてください。
pluginsディレクトリ
pluginsディレクトリはアプリケーション初期化時に実行してくれるもので、アプリケーション全体で利用するものを定義します。
今回は引数で受け取った文字列をHello XXと表示するプラグインを定義してみます。
まずはディレクトリを作成し、ファイルを作成します。
mkdir plugins
code plugins/hello.ts
export default defineNuxtPlugin(() => {
return {
provide: {
hello(msg: string) {
return `Hello ${msg}!`;
},
},
};
});
World
文字列を引数に与えて呼び出してみます。
about.vue
を以下に書き換えましょう。useNuxtApp関数を実行してプラグイン$helloを取り出しています。
<script setup>
const { count, inc, dec } = useCounter(1);
const { $hello } = useNuxtApp();
</script>
<template>
<h1>About Page</h1>
<div>Count:{{ count }}</div>
<div>
<Button @click="() => inc()">increase</button>
<Button @click="() => dec()">decrease</button>
</div>
<h2>{{ $hello('World') }}</h2>
</template>
localhost:3000/about
アクセス時にHello World!
の文字列が表示されます。
middlewareディレクトリ
ミドルウェアはページルーティングが発生する際に実行されます。
今回は/admin
ページへアクセスするための認証ミドルウェアを作成し、クエリパラメータにtest=foo
が含まれるかどうかを判定していきます。
まずはmiddleware
ディレクトリの下にauth.ts
ファイルを作成します。
mkdir middleware
code middleware/auth.ts
以下を貼り付けてください。
URLが/admin
でない場合は403エラーを発生させ、クエリパラメータにtest=foo
が含まれていない場合は/about
にリダイレクトしています。
export default defineNuxtRouteMiddleware((to, from) => {
if (to.path !== '/admin') {
return abortNavigation(
createError({ statusCode: 403, message: '認証されていません' })
);
}
if (to.query.test !== 'foo') {
return navigateTo("/about");
}
});
またadminページも作成します。
code pages/admin.vue
middleware: 'auth'
でauthミドルウェアを呼び出しています。
<script>
definePageMeta({
middleware: 'auth',
});
</script>
<template>
<div>
<h1>Admin Page</h1>
</div>
</template>
それでは以下URLでアクセスしてみましょう。
adminページが表示されれば成功です。また、クエリパラメータの値を変更してアクセスするとaboutページにリダイレクトされることも確認できます。
localhost:3000/admin?test=foo
serverディレクトリ
server
ディレクトリへはAPI Routeを定義します。
今回は/api/hello
にアクセスすると”Hello World”を戻すシンプルなAPI Routeを追加します。
server
ディレクトリへ、api/hello.ts
を作成しましょう。
mkdir -p server/api
code server/api/hello.ts
export default defineEventHandler(() => 'Hello World');
それでは以下URLでAPIを呼び出してみましょう。
Hello World
が表示されるはずです。このように簡単にAPI Routeを定義することができます。
localhost:3000/api/hello
まとめ
Nuxt3ついて今回はフロントサイドを解説しました。
サーバーサイドにも便利な機能が多数あるのでぜひ調べてみてください。
機能が豊富でまた簡単に実装可能であるため、少しでも使ってみたいと思っていただければ幸いです。
ここまで読んでくださりありがとうございました!