今更シリーズ : vue-router4とは/Nuxt3のrouterについて

vue-router4/Nuxt3のrouterについて理解が曖昧だったので調べてみた。

## vue-routerとは

Vue Router4は、Vue.jsフレームワーク用の公式ルーティングライブラリです。
SPA（シングルページアプリケーション）のためのルーティング機能を提供し、異なるページ間のナビゲーションを可能にします。

https://router.vuejs.org/guide/

## 基本的な使い方

Vue Routerを使った基本的なコード例を紹介し、それぞれの機能について説明します。
まずは、Vue Routerの設定の基本形です

```javascript
import { createRouter, createWebHistory } from 'vue-router';
import Home from './components/Home.vue';
import About from './components/About.vue';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About
    }
  ]
});

export default router;
```

このコードでは以下のことを行っています：

1. **Vue Routerをインポート**: Vue Routerライブラリをインポートします。

2. **ルートコンポーネントのインポート**: `Home` と `About` という2つのコンポーネントをインポートします。

3. **ルーターのインスタンスを作成**: `createRouter` でルーターのインスタンスを作成し、各ルートとそれに対応するコンポーネントを定義します。
   - `'/'` のパスで `Home` コンポーネントを表示。
   - `'/about'` のパスで `About` コンポーネントを表示。

4. **エクスポート**: 作成したルーターのインスタンスをエクスポートします。

そして、このルーターをメインのVueインスタンスに適用します：

```javascript
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);
app.use(router);
app.mount('#app');
```

ここでは、Vue 3の `createApp` 関数を使用してメインのVueインスタンスを作成し、先ほど定義したルーターを適用しています。
この設定により、アプリケーションでページ間のナビゲーションが可能になります。

https://v3.router.vuejs.org/ja/guide/#javascript

## createHistoryについて

Vue Router 4で導入された**createHistory**関数は、Vue Routerの履歴管理のために使用されます。
Vue Routerは、アプリケーションのルート（URL）の変更を検知し、適切なコンポーネントを表示するために内部的に履歴を管理します。**createHistory**関数は、この履歴管理をカスタマイズするために使われます。

### createHistoryの種類

Vue Router 4では、主に3種類の履歴管理メソッドが提供されています。

#### 1. **createWebHistory**: 

HTML5 History APIを使用して履歴を管理します。
これにより、クリーンなURL（ハッシュ`#`がない）が提供され、ブラウザの「戻る」「進む」機能がサポートされます。

   ```javascript
   import { createRouter, createWebHistory } from 'vue-router';

   const router = createRouter({
     history: createWebHistory(),
     routes: [...]
   });
   ```

#### 2. **createWebHashHistory**

これはURLのハッシュを使用して履歴を管理します。
古いブラウザとの互換性が必要な場合や、サーバの設定を変更できない場合に適しています。

   ```javascript
   import { createRouter, createWebHashHistory } from 'vue-router';

   const router = createRouter({
     history: createWebHashHistory(),
     routes: [...]
   });
   ```

#### 3. **createMemoryHistory**
 
これは主にサーバサイドでのレンダリングやテスト目的で使用されます。
ブラウザの履歴スタックを使用せず、全ての履歴をメモリ内で管理します。

   ```javascript
   import { createRouter, createMemoryHistory } from 'vue-router';

   const router = createRouter({
     history: createMemoryHistory(),
     routes: [...]
   });
   ```

## ナビゲーションガードについて

Vue Routerのナビゲーションガードは、ルーティングの流れを制御するためのフックです。
これらは主にルート遷移を検知し、特定の条件下で遷移を許可するか、リダイレクトするか、またはキャンセルするために使用されます。
ナビゲーションガードには、大きく分けて「グローバルガード」、「ルート固有ガード」、「コンポーネント内ガード」の3種類があります。

以下に、各タイプのナビゲーションガードの使用例を挙げて説明します。

### グローバルガード

グローバルガードは、ルーターインスタンスに直接設定され、アプリケーション全体のルート遷移に適用されます。

**例：認証が必要なページへのアクセス制御**

```javascript
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record

.meta.requiresAuth)) {
    if (!isLoggedIn()) {
      next({ path: '/login' });
    } else {
      next();
    }
  } else {
    next();
  }
});
```

この例では、`to.matched.some()` を使用して、移動先のルートが認証を必要とするかどうかを判断しています。ユーザーがログインしていない場合は、ログインページにリダイレクトします。

### ルート固有ガード

特定のルートにのみ適用されるガードです。

**例：特定のルートへのアクセス制御**

```javascript
const routes = [
  {
    path: '/admin',
    component: AdminPage,
    beforeEnter: (to, from, next) => {
      if (isAdminUser()) {
        next();
      } else {
        next({ path: '/unauthorized' });
      }
    }
  }
];
```

この例では、`/admin` ルートにアクセスする前にユーザーが管理者かどうかをチェックし、管理者でなければ `/unauthorized` ページにリダイレクトします。

### コンポーネント内ガード

Vueコンポーネント内で定義されるガードです。

**例：ページを離れる前の確認**

```javascript
export default {
  data() {
    return {
      isEditing: false
    };
  },
  beforeRouteLeave(to, from, next) {
    if (this.isEditing && !confirm('変更を破棄しますか？')) {
      next(false);
    } else {
      next();
    }
  }
};
```

この例では、`beforeRouteLeave` ガードを使って、ユーザーが編集中の状態でページを離れようとしたときに、確認ダイアログを表示します。ユーザーがキャンセルを選択した場合、ルート遷移はキャンセルされます。

これらのナビゲーションガードの例は、ルート遷移の流れを柔軟に制御し、ユーザーエクスペリエンスを向上させるのに役立ちます。

[Vue Router 4のナビゲーションガード](https://v3.router.vuejs.org/ja/guide/advanced/navigation-guards.html)

## ネストされたルート

Vue Routerにおけるネストされたルート（Nested Routes）は、アプリケーションのUIが複数の階層を持つ場合に非常に便利です。これにより、親子関係を持つ複数のビュー（コンポーネント）を組み合わせて表示することが可能になります。

### ネストされたルートの設定方法

ネストされたルートは、ルートの設定オブジェクト内で `children` プロパティを使用して定義します。以下にその基本的な構造を示します。

```javascript
const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/parent',
      component: ParentComponent,
      children: [
        {
          path: 'child',
          component: ChildComponent
        }
      ]
    }
  ]
});
```

この例では、`/parent` ルートに `ChildComponent` をネストしています。この場合、`/parent/child` というURLにアクセスすると、`ParentComponent` 内に `ChildComponent` が表示されます。

### 親コンポーネントの設定

ネストされたルートを表示するには、親コンポーネント内に `<router-view>` を配置する必要があります。`<router-view>` は、マッチした子ルートのコンポーネントをレンダリングする場所として機能します。
下記の例で言うと、ユーザーが /parent/child というURLにアクセスしたとき、ParentComponent の <router-view> の場所に ChildComponent が表示されます。

```vue
<template>
  <div>
    <h1>Parent Component</h1>
    <router-view
></router-view> <!-- ここに子コンポーネントが表示されます -->
  </div>
</template>
``` 

## Nuxt3でのrouterについて

Nuxt.jsでは、Vue Routerの機能が内蔵されており、ファイルベースのルーティングを提供しています。
Nuxt.jsを使用すると、Vue Routerの設定を自動的に処理し、開発者はルートの設定に関してほとんど手を加える必要がなくなります。

###  基本的なルートの構成

以下はNuxt.jsにおける基本的なページ構造の例です。

```
pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue
```

この構造では、以下のルートが自動的に作成されます。

- `/` → `pages/index.vue`
- `/user` → `pages/user/index.vue`
- `/user/one` → `pages/user/one.vue`

## Nuxt 3におけるカスタムルーター

Nuxt 3では、"カスタムルーター"はNuxtのデフォルトルーティング挙動をオーバーライドし、独自のルーティングロジックや設定を適用することを指します。Nuxtは通常、pagesディレクトリ内のファイル構造に基づいて自動的にルートを生成しますが、カスタムルーターを使用することで、この自動生成プロセスに手を加えることができます。

```javascript
// nuxt.config.js
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  router: {
    extendRoutes(routes, resolve) {
      routes.push({
        name: 'custom',
        path: '/custom-path',
        component: resolve(__dirname, 'pages/custom.vue')
      });
    }
  }
});
```

この例では、`defineNuxtConfig` 関数を使用して、Nuxtの設定オブジェクトを定義しています。ルーター設定では、`extendRoutes` メソッドを使ってカスタムルートを追加しています。このメソッドは、既存のルート配列を引数として受け取り、新しいルートを追加できます。ここでは、`/custom-path` というパスで `pages/custom.vue` コンポーネントに対応する新しいルートを追加しています。

## 感想

Nuxt３便利だなー