本文へジャンプ

ルーティング

クライアントサイドとサーバーサイドのルーティングの比較

サーバーサイドのルーティングとは、ユーザーがアクセスしている URL のパスに基づいて、サーバーがレスポンスを送信することを意味します。従来のサーバーレンダリングの Webb アプリでリンクをクリックすると、ブラウザーはサーバーから HTML レスポンスを受け取り、新しい HTML でページ全体を再読み込みします。

しかし Single-Page Application(SPA) では、クライアントサイドの JavaScript がナビゲーションを横取りし、動的に新しいデータを取得し、ページを完全に再読み込みすることなく現在のページを更新します。これは一般的に、ユーザーが長期間にわたって多くのインタラクションを実行することが期待される実際の「アプリケーション」のようなユースケースで特に、より迅速なユーザーエクスペリエンスにつながります。

このような SPA では「ルーティング」はクライアントサイド、つまりブラウザーで行われます。クライアントサイドのルーターは、History APIhashchange イベントなどのブラウザー API を使用して、アプリケーションのレンダリングビューを管理する責任を負っています。

公式ルーター

Vue は SPA の構築に適しています。ほとんどの SPA では、公式がサポートする Vue Router ライブラリー を使うことを推奨します。詳細は、Vue Router の ドキュメント を参照してください。

スクラッチでのシンプルなルーティング

もしシンプルなルーティングのみ必要で、フル機能のルーターライブラリーを含めたくない場合は、動的コンポーネントを使って、ブラウザーの hashchange イベント を購読したり、 History API を使うことで、現在のコンポーネントの状態を変更することができます。

以下は、最小構成の例です:

vue
<script setup>
import { ref, computed } from 'vue'
import Home from './Home.vue'
import About from './About.vue'
import NotFound from './NotFound.vue'

const routes = {
  '/': Home,
  '/about': About
}

const currentPath = ref(window.location.hash)

window.addEventListener('hashchange', () => {
  currentPath.value = window.location.hash
})

const currentView = computed(() => {
  return routes[currentPath.value.slice(1) || '/'] || NotFound
})
</script>

<template>
  <a href="#/">Home</a> |
  <a href="#/about">About</a> |
  <a href="#/non-existent-path">Broken Link</a>
  <component :is="currentView" />
</template>

Playground で試す

vue
<script>
import Home from './Home.vue'
import About from './About.vue'
import NotFound from './NotFound.vue'

const routes = {
  '/': Home,
  '/about': About
}

export default {
  data() {
    return {
      currentPath: window.location.hash
    }
  },
  computed: {
    currentView() {
      return routes[this.currentPath.slice(1) || '/'] || NotFound
    }
  },
  mounted() {
    window.addEventListener('hashchange', () => {
		  this.currentPath = window.location.hash
		})
  }
}
</script>

<template>
  <a href="#/">Home</a> |
  <a href="#/about">About</a> |
  <a href="#/non-existent-path">Broken Link</a>
  <component :is="currentView" />
</template>

Playground で試す

ルーティングが読み込まれました