Nuxt3 ステート管理 と interfaces でのグローバル変数

## ■完成イメージ
![スクリーンショット (121).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/4f463a1f-2bcc-fa08-366e-ba9ece0dda67.png)

## ■ソースコード
・app.vue（大枠）
```app.vue

<script setup lang="ts">
import type { Member } from '@/interfaces';

// 会員情報リストをステートとして用意
useState<Map<number, Member>>(
  "memberList", 
  (): Map<number, Member> => {
    const memberListInit = new Map<number, Member>();

    memberListInit.set(1, {id: 1, name: "夏目智徹", email: "t@mail.com", points: 89, 
    note: "入会９か月" });

    memberListInit.set(2, {id: 2, name: "チンギスハーン", email: "ttt@mail.com", points: 67, 
    note: "入会５か月" });

    memberListInit.set(3, {id: 3, name: "バモスるい", email: "bbb@mail.com", points: 99, 
    note: "勧誘中" });

    memberListInit.set(4, {id: 4, name: "るい北澤", email: "jjjj@mail.com", points: 20, 
    note: "" });

    memberListInit.set(5, {id: 5, name: "ハリソン山中", email: "hari@mail.com", points: 50, 
    note: "強制退会" });

    return memberListInit;
  }
);
</script> 

<template>
  <div>
    <TheBaseSection />
  </div>
</template>

```

・TheBaseSection.vue（中コンポーネント）
``` TheBaseSection.vue

<script setup lang="ts">

import type { Member } from '@/interfaces';
import OneMember from './OneMember.vue';

// 会員情報リストを、ステートから取得する
const memberList = useState<Map<number, Member>>("memberList");

// 保有ポイントの合計算出
const totalPoints = computed(
    (): number => {
        let total = 0;
        for (const member of memberList.value.values()) {
            total += member.points;
        }
        return total;
    }
);

</script>

<template>
    <section>
        <h1>会員リスト</h1>
        <p>全会員の保有ポイント 合計： {{ totalPoints }}</p>
        <!-- OneMember コンポーネント呼び出し -->
         <OneMember
            v-for="id in memberList.keys()"
            v-bind:key="id"
            v-bind:id="id" />
    </section>
</template>

<style scoped>

section {border: orange 1px dashed; margin: 10px}

</style>

```
・OneMember.vue（最小コンポーネント）
```OneMember.vue
<script setup lang="ts">

import type { Member } from '@/interfaces';

// Props インターフェイスを定義
interface Props {
    id : number;
}

// Props オブジェクト設定
const props = defineProps<Props>();

// 会員情報リストを　ステートから取得
const memberList = useState<Map<number, Member>>("memberList");
// 該当する会員情報の取得
const member = memberList.value.get(props.id) as Member;

// 備考（note） を加工する算出プロパティ
const localNote = computed(
    (): string => {
        let localNote = member.note;
        // 備考がない場合
        if(localNote == undefined) {
            localNote = '--';
        }
        return localNote;
    }
);

// ポイント加算　ボタン　クリック
const pointUp = (): void => {
    member.points+=1;
}

</script>

<template>
    <section class="box">
        <h4>{{ member.name }} さん</h4>
        <dl>
            <dt>ID</dt>
            <dd>{{ id }}</dd>

            <dt>メールアドレス</dt>
            <dd>{{ member.email }}</dd>

            <dt>保有ポイント</dt>
            <dd>{{ member.points }}</dd>

            <dt>備考</dt>
            <dd>{{ localNote }}</dd>
          
        </dl>

        <button v-on:click="pointUp">ポイント加算</button>

    </section> <!-- ========== section END ======== -->
</template>

<style scoped>

.box { border: green 1px solid;margin: 10px;}

</style>

```

・グローバル
``` interfaces.ts

export interface Member {
    id: number;
    name: string;
    email: string;
    points: number;
    note?: string;
}

```