【ワンピースで覚えるNuxt】ルーティング
ルーティング
Vue Routerではファイルにルーティング情報を追加するが、Nuxtでは不要
NuxtPageタグ
Vue RouterのRouterViewタグに当たるもの
ルートタグで使用不可(別タグで囲む)
画面用のコンポーネント
pagesフォルダに格納
ファイル構造がパスになる(ファイルシステムルータ)
ルート => index.vue
リンク生成
NuxtLinkタグ
リンク先をto属性(v-bind:to)で指定
name: ルーティング名
character/characterList.vue
=> character-characterList(ルーティング名)
ルートパラメータ
[ルートパラメータ名].vue
/character/characterDetail/:id
=> character/characterDetail/[id].vue
useRoute()
ルートオブジェクトを取得
paramsプロパティでパラメータをゲット
ルートパラメータのリンク
リンクにparamsを埋め込む
character/characterDetail/[id].vue
=> character-characterDetail-id, params: {id: id}
ルーティングの制御
ルータオブジェクト useRouter()
pushメソッドで指定の場所へ遷移
app.vue
<script setup lang="ts">
//型定義をインポートするときは import type
import type {Character} from "@/interfaces";
//キャラクターリストデータ。
useState<Map<number, Character>>(
"characterList", //ステート名
(): Map<number, Character> => { //初期値を生成
const characterListInit = new Map<number, Character>();
characterListInit.set(1, {id: 1, name: "ルフィ", bounty: 100000000});
characterListInit.set(2, {id: 2, name: "ゾロ", bounty: 60000000});
return characterListInit;
}
);//characterListでデータの取り出しが可
</script>
<template>
<header>
<h1>ワンピース</h1>
</header>
<main>
<NuxtPage/>
</main>
</template>
<style>
main {
border: black 5px solid;
padding: 10px;
}
#breadcrumbs ul li {
display: inline;
list-style-type: none;
}
#breadcrumbs ul {
padding-left: 0px;
}
#breadcrumbs ul li:before {
content: " > ";
}
#breadcrumbs ul li:first-child:before {
content: none;
}
</style>
pages/index.vue
<template>
<h1>TOP</h1>
<nav id="breadcrumbs">
<ul>
<li>TOP</li>
</ul>
</nav>
<section>
<p>
<!-- <NuxtLink to="/character/characterList"> -->
<NuxtLink v-bind:to="{name: 'character-characterList'}">
キャラクターの設定はこちらから
</NuxtLink>
</p>
</section>
</template>
pages/character/characterList.vue
<script setup lang="ts">
import type {character} from "@/interfaces";
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
</script>
<template>
<h1>キャラクター設定</h1>
<nav id="breadcrumbs">
<ul>
<li><NuxtLink v-bind:to="{name: 'index'}">TOP</NuxtLink></li>
<li>キャラクターリスト</li>
</ul>
</nav>
<section>
<h2>キャラクターリスト</h2>
<p>
追加は<NuxtLink v-bind:to="{name: 'character-characterAdd'}">こちら</NuxtLink>から
</p>
<section>
<ul>
<li
v-for="[id, character] in characterList"
v-bind:key="id">
<NuxtLink v-bind:to="{name: 'character-characterDetail-id', params: {id: id}}">
No:{{id}} {{character.name}}
</NuxtLink>
</li>
</ul>
</section>
</section>
</template>
pages/character/characterAdd.vue
<script setup lang="ts">
import type {character} from "@/interfaces";
//ルータオブジェクトを取得。
const router = useRouter();
// router.push() => 指定の居場所へ
// router.back() => 履歴上で1つ前の画面
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
//入力データと同期させるCharacterオブジェクトの用意。
const character: Character = reactive(
{
id: 0,
name: "",
bounty: 0,
}
);
//登録ボタンが押された時の処理。
const onAdd = (): void => {
characterList.value.set(character.id, character);
router.push({name: "character-characterList"});
};
</script>
<template>
<h1>キャラクター設定</h1>
<nav id="breadcrumbs">
<ul>
<li><NuxtLink v-bind:to="{name: 'index'}">TOP</NuxtLink></li>
<li><NuxtLink v-bind:to="{name: 'character-characterList'}">キャラクターリスト</NuxtLink></li>
<li>キャラクター追加</li>
</ul>
</nav>
<section>
<h2>キャラクター追加</h2>
<p>
情報を入力し、登録ボタンをクリックしてください。
</p>
<form v-on:submit.prevent="onAdd">
<table>
<tr>
<td>
<label for="addId">No:</label>
</td>
<td>
<input type="number" id="addId" v-model.number="character.id" required>
</td>
</tr>
<tr>
<td>
<label for="addName">名前:</label>
</td>
<td>
<input type="text" id="addName" v-model="character.name" required>
</td>
</tr>
<tr>
<td>
<label for="addBounty">懸賞金:</label>
</td>
<td>
<input type="number" id="addBounty" v-model.number="character.bounty" required>
</td>
</tr>
</table>
<br>
<button type="submit">登録</button>
</form>
</section>
</template>
pages/character/characterDetail/[id].vue
<script setup lang="ts">
import type {Character} from "@/interfaces";
//ルートオブジェクト(ルートに関する情報を取得)を取得。
const route = useRoute();
// route.name => character-characterDetail-id
// route.path => /character/characterDetail/1
// route.params => { id: 1 }
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
//キャラクターリストから該当キャラクターを取得。
const character = computed(
(): Character => {
const id = Number(route.params.id);
return characterList.value.get(id) as Character;
}
);
</script>
<template>
<h1>キャラクター設定</h1>
<nav id="breadcrumbs">
<ul>
<li><NuxtLink v-bind:to="{name: 'index'}">TOP</NuxtLink></li>
<li><NuxtLink v-bind:to="{name: 'character-characterList'}">キャラクターリスト</NuxtLink></li>
<li>キャラクター詳細情報</li>
</ul>
</nav>
<section>
<h2>キャラクター詳細情報</h2>
<table>
<tr>
<td>No:</td>
<td>{{character.id}}</td>
</tr>
<tr>
<td>名前:</td>
<td>{{character.name}}</td>
</tr>
<tr>
<td>懸賞金:</td>
<td>{{character.bounty}}ベリー</td>
</tr>
</table>
</section>
</template>