LoginSignup
13
4

フロントエンド開発にNuxt3を使おう

Last updated at Posted at 2024-01-09

はじめに

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

default.png

インストール直後のディレクトリ構造はこのようになっています。
ブラウザ上に表示される内容に関わるファイルは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

そして、以下内容を貼り付けてください。

pages/about.vue
<template>
  <h1>About Page</h1>
</template>

URLを以下に変更してください。

localhost:3000/about

pagesディレクトリにファイルを作成するだけでルーティングしてくれるのでとても便利ですね。

about.png

では、ディレクトリがネストされている場合はどうでしょうか。
pages/user/index.vueファイルを作成しましよう。

mkdir pages/user
code pages/user/index.vue

同様に以下内容を貼り付けてください。

pages/user/index.vue
<template>
  <h1>User Page</h1>
</template>

URLをネストされたディレクトリ名にしたい場合は、index.vueというファイル名で作成しましょう。
するとディレクトリ名でルーティングされます。

localhost:3000/user

user.png

続けて、動的ルーティングしてみましょう。
userのid毎にURLを変えたい場合などに有効です。
ファイル名が少し特殊で[id].vueのようにします。
コマンドベースで作成されない場合は手動作成してください。

pages/user/[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

user-id.png

layoutsディレクトリ

layoutsディレクトリは共通部品を配置します。
今回はヘッダータイトルを配置します。
layoutsディレクトリを作成しdefault.vueを作成しましょう。

mkdir layouts
code layouts/default.vue
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ディレクトリ以下のファイルが展開されます。

app.vue
<template>
  <div>
    <NuxtLayout></NuxtLayout>
    <NuxtPage />
  </div>
</template>

localhost:3000/aboutlocalhost:3000/userにアクセスすると、すべてのページでヘッダータイトルが表示されることがわかります。

componentsディレクトリ

componentsディレクトリにボタンコンポーネントを配置します。
componentsディレクトリを作成し、その下にbutton.vueを作成しましょう。

mkdir components
code components/button.vue
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を以下のように書き換えます。

pages/about.vue
<template>
  <h1>About Page</h1>
  <Button />
</template>

これでボタンコンポーネントが表示可能になります。

components.png

composablesディレクトリ

composablesディレクトリの中にcomposable関数を含むファイルを配置します。
今回は、ボタンクリックをトリガーとして数値をインクリメント、デクリメントする関数を作成してみます。
composablesディレクトリを作成しuseCounter.tsを作成しましょう。

mkdir composables
code composables/useCounter.ts
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でこの関数を読み出すため以下のように変更してください。

pages/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が呼び出されます。

counter.png

assetsディレクトリ

assetsディレクトリは静的ファイルを配置します。
assetsディレクトリを作成し、全体へ適用したいCSSファイルを作成しましょう。

mkdir -p assets/css
code assets/css/style.css

style.cssの中身として以下を貼り付けてください。

assets/css/style.css
body {
  background-color: #FFFFBB;
}

またCSSファイルを読み込ませるため、nuxt.config.tsを以下へ書き換えてください。

nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  devtools: { enabled: true },
  css: [
    "@/assets/css/style.css"
  ],
})

今回は背景へ薄い黄色を設定しました。
どのページへ移動しても背景色が設定されていることが確認できます。

assets.png

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
plugins/hello.ts
export default defineNuxtPlugin(() => {
  return {
    provide: {
      hello(msg: string) {
        return `Hello ${msg}!`;
      },
    },
  };
});

World文字列を引数に与えて呼び出してみます。
about.vueを以下に書き換えましょう。useNuxtApp関数を実行してプラグイン$helloを取り出しています。

pages/about.vue
<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!の文字列が表示されます。

plugins.png

middlewareディレクトリ

ミドルウェアはページルーティングが発生する際に実行されます。
今回は/adminページへアクセスするための認証ミドルウェアを作成し、クエリパラメータにtest=fooが含まれるかどうかを判定していきます。
まずはmiddlewareディレクトリの下にauth.tsファイルを作成します。

mkdir middleware
code middleware/auth.ts

以下を貼り付けてください。
URLが/adminでない場合は403エラーを発生させ、クエリパラメータにtest=fooが含まれていない場合は/aboutにリダイレクトしています。

middleware/auth.ts
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ミドルウェアを呼び出しています。

pages/admin.vue
<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
server/api/hello.ts
export default defineEventHandler(() => 'Hello World');

それでは以下URLでAPIを呼び出してみましょう。
Hello Worldが表示されるはずです。このように簡単にAPI Routeを定義することができます。

localhost:3000/api/hello

api.png

まとめ

Nuxt3ついて今回はフロントサイドを解説しました。
サーバーサイドにも便利な機能が多数あるのでぜひ調べてみてください。
機能が豊富でまた簡単に実装可能であるため、少しでも使ってみたいと思っていただければ幸いです。

ここまで読んでくださりありがとうございました!

13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4