まえがき
この記事では、Next.js(React/JSX)、Nuxt.js(Vue)の、2つの代表的なWebフレームワークを、それぞれの基本的な使い方から、そのメリット・デメリットを比較していきます。
以下のバージョンを対象にしています。
| 名前 | バージョン |
|---|---|
| Next.js | 15.4.6 |
| React | 19.1.0 |
| Nuxt.js | 4.0.3 |
| Vue | 3.5.18 |
NextとNuxtの比較
テンプレートの記法
NextとNuxtで大きく異なる点の1つは、テンプレートの記法です。
NextはJSX(JavaScriptベース)、NuxtはVueテンプレート(HTMLベース)を使用します。
Next(JSX)
export default function Page() {
return (
<div>
<h1>サンプルページ</h1>
<p>このページはサンプルページです。</p>
</div>
);
}
Nuxt(Vueテンプレート)
<template>
<div>
<h1>サンプルページ</h1>
<p>このページはサンプルページです。</p>
</div>
</template>
JSXではexport defaultで関数をエクスポートし、importで外部コンポーネントや機能を読み込みます。
一方Vue(Nuxt)では、HTML構文に近い記法を使い、主要なAPIやコンポーネントは自動インポートされます。
状態管理
状態管理において、両者で大きく異なる点はイミュータブルかどうかです。
Nextでは、ReactのuseStateを使用して、イミュータブルに状態を定義し、
Nuxtでは、Vueのrefを使用して、リアクティブな値を定義します。
Next(App Router)
"use client";
import { useState } from "react";
export default function Page() {
const [num, setNum] = useState(0);
return (
<div>
<button onClick={() => setNum((prev) => prev + 1)}>count up</button>
<div>{num}</div>
</div>
);
}
Nuxt(Composition API)
<script setup>
const num = ref(0);
</script>
<template>
<div>
<button @click="num += 1">count up</button>
<div>{{ num }}</div>
</div>
</template>
Nuxtは簡潔に書くことが可能で、状態変更時に必要な部分だけが再描画されます。
Nextでは、値の更新はセッター関数経由で行い、更新があると関連するコンポーネントが再描画されます。
条件分岐(if)と繰り返し(for)
Next、Nuxt両者とも条件分岐、繰り返しなどの構造処理が可能ですが、それぞれ書き方が大きく異なります。
Nextでは、JavaScript構文(mapや三項演算子)を直接使用し、
Vueでは、v-ifやv-forなどのディレクティブを要素の属性として書きます。
React
条件分岐
export default function Page() {
const age = 18;
return (
<>
{age >= 18 ? (
<div>ようこそ</div>
) : (
<div>18歳未満はご利用できません。</div>
)}
</>
);
}
繰り返し
const tabs = ["top", "blog", "profile"];
export default function Page() {
return (
<div>
{tabs.map((item) => (
<a key={item} href={`/${item}`}>
{item}
</a>
))}
</div>
);
}
Vue
条件分岐
<script setup>
const age = 18;
</script>
<template>
<div v-if="age >= 18">ようこそ</div>
<div v-else>18歳未満はご利用できません。</div>
</template>
繰り返し
<script setup>
const tabs = ["home", "blog", "profile"];
</script>
<template>
<div>
<a v-for="tab in tabs" :key="tab" :href="`/${tab}`">
{{ tab }}
</a>
</div>
</template>
Nextでは、JavaScript構文を使って直感的に書くことが可能ですが、
Nuxtでは簡潔に書ける一方、v-if v-forなど、少し特殊な書き方が必要です。
特にv-for="tab in tabs"など、HTMLやJavaScriptでは見慣れない書き方もあります。
CSSの扱い
Nextでは、CSS ModulesとTailwindCSSが標準サポートされています。
Nuxt(Vue)では、.vueファイル内でHTML・JS・CSSをまとめて記述可能です。
scopedやmodule指定(CSS Modules)が簡単に使用できます。
Next
TailwindCSS
export default function Page() {
return (
<div>
<h1 className="text-red-500 bg-black">サンプルページ</h1>
<p className="m-2">これはサンプルページです。</p>
</div>
);
}
CSS Modules
import styles from "@/styles/page.module.css";
export default function Page() {
return (
<div>
<h1 className={styles.h1}>サンプルページ</h1>
<p className={styles.text}>これはサンプルページです。</p>
</div>
);
}
Nuxt
scoped
<template>
<div>
<h1 class="h1">サンプル</h1>
<p class="text">サンプルテキスト</p>
</div>
</template>
<style scoped>
/* ... */
</style>
module
<template>
<div>
<h1 :class="$style.h1">サンプル</h1>
<p :class="$style.text">サンプルテキスト</p>
</div>
</template>
<style module>
/* ... */
</style>
外部ファイルを使わずにCSSを扱える点はVueの利点です。
まとめ(比較表)
| 項目 | Next(React) | Nuxt(Vue) |
|---|---|---|
| 記法 | JSX(JavaScriptベース) | Vueテンプレート(HTMLベース) |
| 状態管理 | useState(イミュータブル、セッター必須) | refやreactive(直接代入で更新) |
| 条件分岐・ループ | JavaScript構文(? :やmap) | ディレクティブ(v-if、v-for) |
| イベント記法 | onClick(関数) | @click(インライン式または関数) |
| CSS | CSS Modules / TailwindCSS | グローバル / scoped / module を.vue内に記述可能 |
| インポート | 明示的にimportが必要 | 多くのAPIやコンポーネントは自動インポート |
| 学習曲線 | JS慣れしていれば直感的 | HTML慣れしていれば直感的 |
感想
私は元々Reactを知っていた都合で、Nextを使用していたのですが、
今回の比較を通じて、Nuxtのシンプルさと開発効率の良さがとても気に入りました。
実はこのサイトはNuxtで作っていまして、Next・TailwindCSSを使った開発とはまた一風変わった感じで、新鮮な気持ちで制作できました。
今回で、Next/Nuxtそれぞれでサイト制作をしてみて、NextもNuxtも良い点があってどちらもすごく使いやすいと感じました。
個人的にはNuxtの簡潔さがとても気に入っているので、今後はNuxtを積極的に使用していこうと思っています。
以上です。ここまで読んでいただき、ありがとうございました。
今後もこのような記事を書いていこうと思っていますので、もしよければまた見に来ていただけたら嬉しいです。
