TL;DR
- Vue 3.5 が 2024‑09 にリリース。内部最適化と
defineModel
などの改善が入った minor 版。
- Next.js 15.3 (2025‑04‑17) は Turbopack がほぼ完成し、React Server Components の扱いが議論中。
- JSX 脳からテンプレート脳へ:
() => <div>{{count}}</div>
から <template><div>{{ count }}</div></template>
へ。
- Composition API と React Hooks は「関数で状態をカプセル化する」という点で同型だが、実装は reactivity system と state queue で異なる。
- Nuxt 3 はファイルベースルーティングと Nitro によるハイブリッドレンダリングを実装。
- 状態管理は Pinia が Redux/Zustand と同じ「central store + useStore」の DX。
- TypeScript × Volar で IDE 体験は React/TypeScript と遜色なし。
- 開発時には Vue Devtools / Nuxt DevTools を活用。
目次
- はじめに
- Vue エコシステム概観
- テンプレート構文 vs JSX
- Composition API と Hooks の違い
- Single‑File Component とディレクトリ設計
- ルーティング & データフェッチ
- 状態管理 (Pinia) vs Redux/Zustand
- SSR / SSG / ハイブリッドレンダリング
- 型安全と IDE 体験
- テスト戦略とツール
- パフォーマンス最適化 Tips
- 移行チェックリスト
- まとめ & 所感
- 付録: よくあるハマりどころ FAQ
はじめに
Next.js (React) で日々開発してきた筆者が、Vue 3.5 と Nuxt 3 をキャッチアップした際の「頭の切り替えポイント」をまとめた比較記事です。比較対象は Next.js 15.x (App Router + React Server Components がデフォルト) とし、コードは TypeScript ベースで記載しています。
対象読者
- React & Next.js の経験がある
- Vue をまだ触ったことがない、あるいは少し触っただけ
- フレームワークの内部アーキテクチャや DX に興味がある
Vue エコシステム概観
要素 |
Vue 周辺 |
React/Next.js 周辺 |
UI ライブラリ |
Vue 3.5 core, <script setup>
|
React 18 concurrent, Server Components |
フルスタック FW |
Nuxt 3 (Nitro, hybrid) |
Next.js 15 (App Router) |
状態管理 |
Pinia (Vuex 5 相当) |
Redux Toolkit, Zustand |
ビルドツール |
Vite 5 (dev) / Nitro (prod) |
Turbopack (dev) / Webpack 5 |
DevTools |
Vue Devtools, Nuxt DevTools |
React DevTools, Next.js overlay |
Vue は official router, official state management, official SSR が揃っており「フレームワーク標準」が厚い。React は逆に「選択肢が豊富」。
テンプレート構文 vs JSX
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
{count}
</button>
);
}
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
JSX からテンプレートへの翻訳早見表
JSX |
Vue テンプレート |
className |
class |
onClick={fn} |
@click="fn" |
style={{ color: 'red' }} |
:style="{ color: 'red' }" |
cond && <A/> |
<A v-if="cond" /> |
Composition API と Hooks の違い
項目 |
Composition API |
React Hooks |
根本原理 |
Proxy ベース reactivity |
State queue & reconciliation |
状態更新 |
ref / reactive (mutable) |
useState (immutable) |
再評価粒度 |
依存単位 |
コンポーネント単位 |
watchEffect
は useEffect
に近いが依存を自動収集するため deps 配列が不要です。
Single‑File Component とディレクトリ設計
-
.vue
に <template>
, <script setup>
, <style scoped>
を内包
- CSS Modules は
<style module>
を利用
- デフォルトでローカル CSS スコープがあるためグローバルリークを防止しやすい
例 (Nuxt 3):
pages/
index.vue
users/
[id].vue
components/
ui/
Button.vue
layout/
Header.vue
ルーティング & データフェッチ
ルーティング比較
フレームワーク |
動的ルート |
グループ化 |
Nuxt 3 |
[id].vue |
なし |
Next.js 15 |
[id]/page.tsx |
(group) ディレクトリ |
データフェッチ
層 |
Next.js |
Nuxt 3 |
クライアント |
useSWR , RSC fetch
|
useFetch , useAsyncData
|
サーバ |
Server Actions, ランタイム再検証 |
defineNuxtRouteMiddleware , API route |
状態管理 (Pinia) vs Redux/Zustand
Pinia は store オブジェクトがそのままリアクティブなので、selector
を追加で書く必要がありません。また defineStore
による型推論で DX が高いです。
SSR / SSG / ハイブリッドレンダリング
トピック |
Next.js |
Nuxt 3 |
SSG |
generateStaticParams + export
|
nuxi generate |
SSR |
デフォルト (streaming) |
nuxi build + Node/Edge |
Edge |
Vercel Edge Runtime |
Nitro preset (Cloudflare 等) |
型安全と IDE 体験
- Volar により
<template>
でも型エラーが赤線表示される
-
defineModel<T>()
で双方向バインディングも型安全
- Nuxt DevTools は Pinia store の値をそのまま確認できる
テスト戦略とツール
レイヤ |
React/Next.js |
Vue/Nuxt |
ユニット |
Vitest, Jest |
Vitest, Vue Test Utils |
コンポーネント |
Testing Library |
Testing Library/vue |
E2E |
Playwright, Cypress |
Playwright, Cypress |
パフォーマンス最適化 Tips
-
v-memo
(Vue 3.4) で再レンダリング制御
- 自動バッチングは Vue がデフォルト実装
- Vite 5 + Rollup による ESM 分割でバンドルサイズ削減
移行チェックリスト
まとめ & 所感
React 脳から Vue へはテンプレート構文に慣れることが最大の壁。しかし Composition API と Pinia によりロジック層の移植は容易でした。Vite + Volar + DevTools の DX は非常に高く、学習コストを払う価値があります。
付録: よくあるハマりどころ FAQ
症状 |
対処 |
value of undefined |
ref / reactive のスコープを確認 |
vue-router catch error |
動的 import コンポーネントで defineProps を忘れていないか |
HMR で Pinia store が初期化 |
acceptHMRUpdate を追記 |
参考リンク
Discussion