Nuxt3 ステート管理、useState、Pinia

## ■ useState での実装

### ●ディレクトリ構成
・app.vue
・pages/state/index.vue
・components/CounterDisolay.vue
・components/CounterButton.vue

・components/CounterDisolay.vue と、・components/CounterButton.vueで`useState` を使って変数（状態）を共有する。

### ●画面
![スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/5dead503-3fee-43a8-9b1b-4ca9d73b319d.png)

### ●ソースコード
```app.vue

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
```
・pages/state/index.vue
```pages/state/index.vue

<template>
    <div class="p-4">
        <h1 class="text-xl font-bold">Nuxt3 useState 使用</h1>
        <p>コンポーネントを下記にて、呼び出し</p>
        <CounterDisolay />
        <CounterButton />
    </div>
</template>

<script setup lang="ts">
import CounterDisolay from '~/components/CounterDisolay.vue';
import CounterButton from '~/components/CounterButton.vue';
</script>

```
・components/CounterDisolay.vue
```components/CounterDisolay.vue
<template>
    <p class="mt-4 text-lg">
        現在のカウント：{{ count }}
    </p>
</template>

<script setup lang="ts">
const count = useState('counter', () => 0)
</script>
```

・components/CounterButton.vue
```components/CounterButton.vue

<template>
     <button @click="increment" class="mt-2 px-4 py-2 bg-blue-500 text-white rounded">
        カウント プラス １
    </button>
</template>

<script setup lang="ts">

const counter = useState('counter', () => 0)
const increment = () => {
    counter.value +=1
}

</script>

```

## ■ Pinia での実装

### ●ディレクトリ構成
・app.vue
・pages/statepinia/index.vue
・components/CountViewerPinia.vue
・components/CountControlPinia.vue
・store/counter.ts
・plugins/pinia.ts

・components/CountViewerPinia.vue と、・components/CountControlPinia.vueと、store/counter.ts、で`Pinia` を使って変数（状態）を共有する。

### ●画面

![スクリーンショット (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/1076ba74-759d-48f8-9238-1032072945ef.png)


### ●ソースコード
```app.vue

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
```

```pages/statepinia/index.vue

<template>
    <div>
        <NuxtLink to="/state">Useステート（UseState）でのデータのやり取り</NuxtLink>
    </div>
    <div>
        <NuxtLink to="/statepinia">Pinia でのデータのやり取り</NuxtLink>
    </div>
</template>

<script setup lang="ts">

</script>

```

```components/CountViewerPinia.vue
<template>
     <p class="mt-4 text-lg">
        現在のカウント：{{ count.count }}
    </p>
</template>

<script setup lang="ts">
import { useCounterStore } from '~/store/counter';

// オブジェクトで取得
// "$id": "counter", "count": 0, "_isOptionsAPI": true
const count = useCounterStore()
</script>
```

```components/CountControlPinia.vue
<template>
    <p class="mt-4 text-lg">
        現在のカウント：{{ count }}
    </p>
</template>

<script setup lang="ts">
const count = useState('counter', () => 0)
</script>
```

```store/counter.ts
import { defineStore } from "pinia";

export const useCounterStore = defineStore('counter', {
    state: () => ({
        count: 0
    }),
    actions: {
        increment() {
            this.count +=1
        }
    }
})
```

```plugins/pinia.ts
import { defineNuxtPlugin } from "#app";
import { createPinia } from "pinia";

// === Nuxt3 で、 pinia の準備
export default defineNuxtPlugin((nuxtApp) => {
    const pinia = createPinia()
    nuxtApp.vueApp.use(pinia)
})

```