🛣

URLが可変になる場合の遷移についてまとめた

2024/03/17に公開

はじめに

会員登録など会員ごとにページができるような場合の routing についてまとめていく
ページ名が可変になるパターンの備忘録

フォルダ構成とファイル名

フォルダ構成はこんな感じ
pages 配下に[id].vue みたいなファイルを置く
この id が動的に動く想定
動的に変わるファイル名は[]で囲う

遷移後のページ([id].vue )の記述

[id].vue 内には下記のように書く
useRoute()でルートパラメータを取得する

[id].vue
<script lang="ts" setup>
import { useRoute } from "vue-router";
// ルートオブジェクトを取得
const route = useRoute();
const id = route.params.id;
console.log(route);
</script>

<template>
  <div>
    <div>id:{{ id }}</div>
    <NuxtLink to="/route/">routeへ</NuxtLink>
  </div>
</template>

useRoute では下記の情報が取得できる

  • fullPath:すべてのパス文字列
  • name:ルーティング名
  • path:query と hash を除いたパス文字列
  • hash:#以降の文字列
  • query:?移行の文字列
  • params:ルートパラメータ、オブジェクト形式
  • redirectedFrom:現在のページに遷移する前にアクセスしようとしたルート

公式ドキュメント
https://nuxt.com/docs/api/composables/use-route

遷移前のページの記述

name の中にはパスを-区切りにしたものを記述する
今回のパスは route/[id].vue なので、route-id になる

index.vue
<script lang="ts" setup>
// 仮の会員リスト
const members = [
  { id: "001", name: "山田 一郎" },
  { id: "002", name: "山田 次郎" },
  { id: "003", name: "山田 三郎" },
  { id: "004", name: "山田 四郎" },
  { id: "005", name: "山田 五郎" },
];
</script>

<template>
  <div>
    <ul>
      <li v-for="member in members">
        <NuxtLink :to="{ name: 'route-id', params: { id: member.id } }">
          id:{{ member.id }}/name:{{ member.name }}
        </NuxtLink>
      </li>
    </ul>
  </div>
</template>

  • 遷移前のページ
  • 遷移後のページ

URL を見るとうまく遷移できてるのがわかる

他のパターン

これまではシンプルなパターンで、末尾のファイル名が動的なパターンだが他のパターンについてもまとめていく
ざっとこんな感じ

[address]/[id].vue のパターン

ルートパラメータが2個あっても大丈夫

<ul>
  <li v-for="member in members">
    <NuxtLink
      :to="{
        name: 'route-address-id',
        params: { id: member.id, address: member.address },
      }"
    >
      id:{{ member.id }}/name:{{ member.name }}/address:{{ member.address }}
    </NuxtLink>
  </li>
</ul>

[address]/[id]-hoge.vue のパターン

ルートパラメータに固定文字がついていても大丈夫

<ul>
  <li v-for="member in members">
    <NuxtLink
      :to="{
        name: 'route-address-id',
        params: { id: `${member.id}-hoge`, address: member.address },
      }"
    >
      id:{{ member.id }}/name:{{ member.name }}/address:{{ member.address }}
    </NuxtLink>
  </li>
</ul>

[address]/[[optionId]].vue のパターン

optionId がなくても、address があれば遷移できる

<ul>
  <li>
    <NuxtLink
      :to="{
        name: 'route-address-optionId',
        params: {
          optionId: '001',
          address: 'hokkaido',
        },
      }"
      >optionId有
    </NuxtLink>
  </li>
  <li>
    <NuxtLink
      :to="{
        name: 'route-address-optionId',
        params: {
          address: 'hokkaido',
        },
      }"
      >optionId無
    </NuxtLink>
  </li>
</ul>
  • optionId 有
  • optionId 無

[address]/[...ids].vue のパターン

id が複数ある場合にも対応できる

<ul>
  <li>
    <NuxtLink
      :to="{
        name: 'route-address-ids',
        params: { ids: ['001', '002', '003'], address: 'hokkaido' },
      }"
    >
      [...ids].vue
    </NuxtLink>
  </li>
</ul>

遷移前のソース

サンプルコード
<script lang="ts" setup>
// 仮の会員リスト
const members = [
  { id: '001', name: 'yamada-ichiro', address: 'hokkaido' },
  { id: '002', name: 'yamada-jiro', address: 'tokyo' },
  { id: '003', name: 'yamada-saburo', address: 'okinawa' },
];
const members2 = [
  { id: ['001'], name: 'yamada-ichiro', address: 'hokkaido' },
  { id: ['002', '002'], name: 'yamada-jiro', address: 'tokyo' },
  { id: ['003', '003', '003'], name: 'yamada-saburo', address: 'okinawa' },
];
</script>

<template>
  <div>
    <h2>[id].vue</h2>
    <ul>
      <li v-for="member in members">
        <NuxtLink
          :to="{
            name: 'route-address-id',
            params: { id: member.id, address: member.address },
          }"
        >
          id:{{ member.id }}/name:{{ member.name }}/address:{{ member.address }}
        </NuxtLink>
      </li>
    </ul>
    <h2>[id]-hoge.vue</h2>
    <ul>
      <li v-for="member in members">
        <NuxtLink
          :to="{
            name: 'route-address-id',
            params: { id: `${member.id}-hoge`, address: member.address },
          }"
        >
          id:{{ member.id }}/name:{{ member.name }}/address:{{ member.address }}
        </NuxtLink>
      </li>
    </ul>
    <h2>[[optionId]].vue</h2>
    <ul>
      <li>
        <NuxtLink
          :to="{
            name: 'route-address-optionId',
            params: {
              optionId: '001',
              address: 'hokkaido',
            },
          }"
          >optionId有
        </NuxtLink>
      </li>
      <li>
        <NuxtLink
          :to="{
            name: 'route-address-optionId',
            params: {
              address: 'hokkaido',
            },
          }"
          >optionId無
        </NuxtLink>
      </li>
    </ul>
    <h2>[...ids].vue</h2>
    <ul>
      <li>
        <NuxtLink
          :to="{
            name: 'route-address-ids',
            params: { ids: ['001', '002', '003'], address: 'hokkaido' },
          }"
        >
          [...ids].vue
        </NuxtLink>
      </li>
    </ul>
  </div>
</template>

Discussion