
レイアウト機能
layoutsフォルダに作成しタグで囲む
デフォルトで適用するにはdefault.vue
デフォルト以外を使用する場合
definePageMeta()を使用する
app.vue
<script setup lang="ts">
//型定義をインポートするときは import type
import type {Character} from "@/interfaces";
const SITE_TITLE = "ワンピース";
//キャラクターリストデータ。
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>
<NuxtLayout>
<NuxtPage/>
</NuxtLayout>
</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>
layouts/default.vue
<template>
<header>
<h1>ワンピース!</h1>
</header>
<main>
<slot/>
</main>
</template>
layouts/character.vue
<template>
<header>
<h1>ワンピース!</h1>
</header>
<main>
<h1>キャラクター設定</h1>
<slot/>
</main>
</template>
pages/character/characterList.vue
<script setup lang="ts">
import type {character} from "@/interfaces";
definePageMeta({
layout: "character"
});
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
</script>
<template>
<nav id="breadcrumbs">
<ul>
<li><NuxtLink v-bind:to="{name: 'index'}">TOP</NuxtLink></li>
<li>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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";
definePageMeta({
layout: "character"
});
//ルータオブジェクトを取得。
const router = useRouter();
// router.push() => 指定の居場所へ
// router.back() => 履歴上で1つ前の画面
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
//入力データと同期させるCharacterオブジェクトの用意。
const character: Character = reactive(
{
id: 3,
name: "",
bounty: 0,
}
);
//登録ボタンが押された時の処理。
const onAdd = (): void => {
characterList.value.set(character.id, character);
router.push({name: "character-characterList"});
};
</script>
<template>
<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>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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";
definePageMeta({
layout: "character"
});
//ルートオブジェクト(ルートに関する情報を取得)を取得。
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>
<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>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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>
ヘッダー情報
useHead()
プロパティに設定したい情報を渡す
titleTemplate
titleのテンプレート設定できる
app.vue
<script setup lang="ts">
//型定義をインポートするときは import type
import type {Character} from "@/interfaces";
const SITE_TITLE = "ワンピース";
useHead({
//title: SITE_TITLE
titleTemplate: (titleChunk: string|undefined): string => {
return titleChunk != undefined ? `${titleChunk} | ${SITE_TITLE}` : SITE_TITLE;
}
});
//キャラクターリストデータ。
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>
<NuxtLayout>
<NuxtPage/>
</NuxtLayout>
</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/character/characterList.vue
<script setup lang="ts">
import type {character} from "@/interfaces";
definePageMeta({
layout: "character"
});
const PAGE_TITLE = "キャラクターリスト";
useHead({
title: PAGE_TITLE,
});
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
</script>
<template>
<nav id="breadcrumbs">
<ul>
<li><NuxtLink v-bind:to="{name: 'index'}">TOP</NuxtLink></li>
<li>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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";
definePageMeta({
layout: "character"
});
const PAGE_TITLE = "キャラクター追加";
useHead({
title: PAGE_TITLE,
});
//ルータオブジェクトを取得。
const router = useRouter();
// router.push() => 指定の居場所へ
// router.back() => 履歴上で1つ前の画面
//キャラクターリストをステートから取得。
const characterList = useState<Map<number, Character>>("characterList");
//入力データと同期させるCharacterオブジェクトの用意。
const character: Character = reactive(
{
id: 3,
name: "",
bounty: 0,
}
);
//登録ボタンが押された時の処理。
const onAdd = (): void => {
characterList.value.set(character.id, character);
router.push({name: "character-characterList"});
};
</script>
<template>
<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>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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";
definePageMeta({
layout: "character"
});
const PAGE_TITLE = "キャラクター詳細情報";
useHead({
title: PAGE_TITLE,
});
//ルートオブジェクト(ルートに関する情報を取得)を取得。
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>
<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>{{PAGE_TITLE}}</li>
</ul>
</nav>
<section>
<h2>{{PAGE_TITLE}}</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>