見出し画像

【ワンピースで覚えるNuxt】サーバ機能(API)


サーバー機能

serverフォルダ

APIエンドポイントとしてデータを送信する場合(apiフォルダ)

defineEventHandler()

自動でJSONデータ化

配列やオブジェクトをreturnすれば良い

getQuery()

eventオブジェクトのクエリパラメータを取り出す

各パラメータ名を指定する

URLSearchParams

クエリ文字の自動生成

引数で元となるデータを渡す

$fetch

GETアクセスを行なってくれる

アクセル先のURLを渡すだけ

charactersDB.ts

import type { Character } from "@/interfaces";

export function createCharacterList(): 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;
}

server/api/getOneCharacterInfo.ts

import type {Character} from "@/interfaces";
import {createCharacterList} from "@/charactersDB";

export default defineEventHandler(
  (event): Character => {
    //クエリパラメータを取得。
    const query = getQuery(event);
    //オブジェクトを生成。
    const characterList = createCharacterList();
    const idNo = Number(query.id);
    const character = characterList.get(idNo) as Character;
    return character;
  }
);

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 }

//アクセス先URLのクエリパラメータ以外を用意。
const characterInfoUrl = "/api/getOneCharacterInfo";
//クエリパラメータの元データを用意。
const params:{
  id: string;
} =
{
  //idのクエリパラメータ
  id: route.params.id,
}
//クエリパラメータを生成。
const queryParams = new URLSearchParams(params);
//URL完成。
const urlFull = `${characterInfoUrl}?${queryParams}`;
//URLに非同期でアクセスしてデータを取得。
const character = await $fetch(urlFull) as any;
//awaitを使用しているので、戻り値はJSONデータ
//複雑な型の場合はany型に変換する
//console.log(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>

ここから先は

25,295字

¥ 100

この記事が気に入ったらチップで応援してみませんか?