ルーティング遷移

この章では、Vue Router を使ってフロントエンドとバックエンドを分離したページ遷移を実装する方法を学びます。動的ルーティングパラメータも含みます。


なぜルーティングを使うのか?

従来の多ページWebサイトでは、リンクをクリックするとサーバーに新しいHTMLファイルをリクエストし、ページ全体がリフレッシュされて、白い画面が一瞬表示されていました。

Vue Router が実現しているのはフロントエンドルーティング:URL が変化してもサーバーにリクエストを送らず、JS が表示するコンポーネントを動的に切り替えます。

これによる利点は次のとおりです:リフレッシュなしでページを切り替えられ、ネイティブアプリのように滑らかな操作感。


Vue Router の中核概念

概念役割対応するコード
ルーティングテーブルURLパスとコンポーネントのマッピング関係を定義するroutes配列
ルーティング出口マッチしたコンポーネントが表示される位置<RouterView />
ナビゲーションリンククリックすると指定したルートに遷移する<RouterLink to="...">
動的ルーティングURLに変数が含まれる(記事IDなど)/post/:id

インストールと設定

プロジェクト作成時に Router を選択した場合は、インストール手順をスキップできます。

選択していない場合は、ターミナルで次のコマンドを実行します:

$ npm install vue-router@4

ルーティング設定ファイルの作成

例

// 文件路径:src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

// 路由表:每条记录映射一个路径到一个组件
const routes = [
  {
    path: '/',                // URL 路径
    name: 'home',             // 路由名称(可选,编程式导航时用)
    component: HomeView       // 対応するページコンポーネント
  },
  {
    // 動的ルート::id はプレースホルダーで、任意の値にマッチします
    // /post/1、/post/2、/post/hello はすべてこのルートに一致します
    path: '/post/:id',
    name: 'post',
    // 遅延読み込み:アクセス時に読み込まれ、ビルド時に独立したJSファイルとして分割される
    component: () => import('../views/PostView.vue')
  }
]

// 创建路由实例
const router = createRouter({
  history: createWebHistory(),  // 使用 HTML5 History 模式(URL 看起来像普通路径)
  routes                         // 注册路由表
})

export default router

2つのルーティングモードの違い:createWebHistoryクリーンなURL(/post/1)を生成し、サーバー設定のサポートが必要です。デプロイ環境が不明な場合は、次を使用できます。createWebHashHistory、URLに # が含まれ(/#/post/1)、サーバー設定は不要です。

main.js でルーティングを登録する

例

<!-- 文件路径:src/App.vue -->
<script setup>
import NavBar from './components/NavBar.vue'
</script>

<template>
  <NavBar />
  <main>
<!-- RouterView は魔法の位置です:現在のルートにマッチしたコンポーネントはここでレンダリングされます -->
    <RouterView />
  </main>
</template>

RouterViewルーティングシステムの中核となる出力先です。

の場合、HomeView をレンダリングします。URL が/の場合、PostView をレンダリングします。/post/1RouterLink — 宣言的ナビゲーション


RouterLink — 宣言的ナビゲーション

RouterLinkタグの代わりになります。<a>ページのリフレッシュは発生せず、JS で表示するコンポーネントを切り替えるだけです。

例

例

<template>
  首页
  <RouterLink to="/"><!-- 名前付きルートの書き方(推奨:パスが変わっても1箇所変更するだけ) --></RouterLink>

  阅读文章 {{ article.id }}
  <RouterLink :to="{ name: 'post', params: { id: article.id } }">
<!-- 传统 a 标签会导致页面刷新,不要用 -->
  </RouterLink>

  <!-- <a href="/post/1">阅读全文</a> -->
  useRoute — ルーティングパラメータの読み取り
</template>

useRoute — ルーティングパラメータの読み取り

現在のルーティング情報を読み取るためのものです。

useRoute例

例

// useRoute は現在のルートオブジェクトを返す
<script setup>
import { useRoute } from 'vue-router'

// route.params には URL 内のパラメータが含まれています
const route = useRoute()

// 例えば URL が /post/3 の場合、route.params.id === '3'
console.log('文章 ID:', route.params.id)
文章详情页
</script>

<template>
  <div>
    <h1><!-- 注意:params の値はすべて文字列です --></h1>
    当前文章 ID:{{ route.params.id }}
    <p>の値は常に文字列です。たとえ URL が</p>
  </div>
</template>

route.params.id、取得されるのも/post/3であり、数値ではありません'3'。数値が必要な場合は、3変換します。Number(route.params.id) 或 parseInt実際にやってみよう:完全な記事詳細ページ


実際にやってみよう:完全な記事詳細ページ

ステップ1:BlogCard をクリック遷移に対応させる

ステップ1:BlogCard をクリック遷移に対応させる

例

id: Number, // 新增:文章 ID,用于跳转
<script setup>
defineProps({
<!-- カード全体が RouterLink で包まれており、どこをクリックしても遷移できます -->
  title: String,
  summary: String,
  date: String,
  category: String
})
</script>

<template>
  ステップ2:PostView 詳細ページを作成する
  <RouterLink :to="{ name: 'post', params: { id } }" class="card-link">
    <div class="card">
      <span class="tag">{{ category }}</span>
      <h3>{{ title }}</h3>
      <p>{{ summary }}</p>
      <span class="date">{{ date }}</span>
    </div>
  </RouterLink>
</template>

<style scoped>
.card-link { text-decoration: none; color: inherit; display: block; }
.card {
  background: #fff;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
  transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.tag {
  display: inline-block;
  padding: 2px 10px;
  background: #E8EEF5;
  color: #427DB8;
  border-radius: 12px;
  font-size: 12px;
}
.card h3 { margin: 10px 0 8px; font-size: 18px; }
.card p { color: #666; font-size: 14px; line-height: 1.6; }
.date { font-size: 12px; color: #999; }
</style>

ステップ2:PostView 詳細ページを作成する

例

例

// 所有文章数据(后续章节会抽离到公共模块)
<script setup>
import { ref, computed } from 'vue'
import { useRoute, RouterLink } from 'vue-router'

const route = useRoute()
const id = Number(route.params.id)

title: 'Vue3 入门完全指南',
const articles = ref([
  {
    id: 1,
summary: 'ゼロから Vue3 コンポジション API を学ぶ',
なぜVue3を学ぶのか?
    category: 'Vue',
    date: '2024-05-10',
    content: `
      <h2>Vue3 は現在最も人気のあるフロントエンドフレームワークの一つで、学びやすく、柔軟で、性能に優れています。</h2>
      <p>コンポジション API の利点</p>
      <h2>Vue2 のオプション API と比較して、コンポジション API はロジックの再利用を簡単にし、コード構成をより柔軟にします。</h2>
      <p>ref と reactive</p>
      <h2>ref は基本型データに適しており、reactive はオブジェクトや配列に適しています。ただし、実際の開発では ref を統一して使用することを推奨します。</h2>
      <p>title: 'JS 异步编程详解',</p>
    `
  },
  {
    id: 2,
summary: 'Promise と async/await を理解する',
非同期とは何ですか?
    category: 'JavaScript',
    date: '2024-05-08',
    content: `
      <h2>JSはシングルスレッドであり、非同期操作によりメインスレッドをブロックせず、ネットワークリクエストやタイマーなどのタスクを同時に処理できます。</h2>
      <p>Promise の核心概念</p>
      <h2>Promise 有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。</h2>
      <p>// 根据 ID 查找文章</p>
    `
  }
])

<!-- 記事は存在しません -->
const article = computed(() => {
  return articles.value.find(a => a.id === id)
})
</script>

<template>
  <div class="post-view">
    記事が存在しません
    <div v-if="!article" class="not-found">
      <h2>ID が {{ id }} の記事が見つかりません</h2>
      <p>返回首页</p>
      <RouterLink to="/"><!-- 記事が存在する場合は、完全な内容を表示 --></RouterLink>
    </div>

    <!-- v-html 渲染 HTML 字符串 -->
    <article v-else>
      <span class="category-tag">{{ article.category }}</span>
      <h1>{{ article.title }}</h1>
      <time>{{ article.date }}</time>
      ← 返回首页
      <div class="content" v-html="article.content"></div>
      <RouterLink to="/" class="back-link">HTML 文字列をレンダリングするために使いますが、注意が必要です:ユーザーが入力した内容をレンダリングするために使わないでください。そうしないと XSS のセキュリティリスクがあります。ここでの記事コンテンツは開発者自身が書いたものなので安全です。</RouterLink>
    </article>
  </div>
</template>

<style scoped>
.post-view {
  max-width: 720px;
  margin: 40px auto;
  padding: 0 20px;
}

.category-tag {
  display: inline-block;
  padding: 4px 12px;
  background: #E8EEF5;
  color: #427DB8;
  border-radius: 12px;
  font-size: 13px;
  margin-bottom: 12px;
}

h1 {
  font-size: 32px;
  margin-bottom: 12px;
  line-height: 1.4;
}

time {
  display: block;
  color: #999;
  font-size: 14px;
  margin-bottom: 30px;
}

.content {
  line-height: 1.8;
  font-size: 16px;
  color: #333;
}

.content :deep(h2) {
  margin: 24px 0 12px;
  font-size: 22px;
}

.content :deep(p) {
  margin-bottom: 12px;
}

.back-link {
  display: inline-block;
  margin-top: 40px;
  color: #427DB8;
  text-decoration: none;
}

.not-found {
  text-align: center;
  padding: 60px 0;
}
</style>

v-html本章のまとめ


本章のまとめ

この章では、Vue Router のコアな使い方を学びました:ルーティングテーブルの設定(path を component にマッピング)、RouterLink によるナビゲーション、RouterView のアウトレット、動的ルート /post/:id、そして useRoute によるルートパラメータの読み取りです。

今、ブログは真のマルチページ体験を実現しました——ホームページで一覧を閲覧し、クリックして詳細ページに入り、完全な内容を読むことができます。

その他の拡張機能