Nuxt3入門チュートリアル(2)

## 概要

Nuxt3ではVue3の機能が使えるようになっているので、Vue3の機能をNuxt3で実際に試していきます。

## 前提

https://qiita.com/Eustace/private/95c2ccc86e8824cb3d6d#nuxt3%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83%E3%81%AE%E6%BA%96%E5%82%99

上記に記載している、「Nuxt3実行環境の準備」からNuxt3のサンプルアプリケーションのStackBlitzを起動してください。

## Stateの管理

https://v3.nuxtjs.org/guide/features/state-management

### ボタンによる値の変更

`app.vue` を以下のように編集してみましょう。

```vuejs:app.vue
<template>
  <div>
    Counter: {{ counter }}
    <button v-on:click="counter++">
      +
    </button>
    <button v-on:click="counter--">
      -
    </button>
  </div>
</template>

<script setup lang="ts">
const counter: Ref<number> = useState('counter', () => 500)
</script>
```

画面上に500という数字が表示されて、プラスとマイナスをクリックすると数字が増減できればOKです。
上記のサンプルでは、 `useState` により `counter` という状態を保存できるようにしていて、初期値が500としています。


`v-on:click` というのがイベントハンドラの登録となります。詳細は以下のページが参考になります。

https://v3.ja.vuejs.org/guide/events.html#%E3%82%A4%E3%83%98%E3%82%99%E3%83%B3%E3%83%88%E3%81%AE%E8%B3%BC%E8%AA%AD

## Vueの省略記法

`v-on:` キーワードは `@` に変更できるので、上記のコードは以下と等価となります。

```vuejs:app.vue
<template>
  <div>
    Counter: {{ counter }}
    <button @click="counter++">
      +
    </button>
    <button @click="counter--">
      -
    </button>
  </div>
</template>

<script setup lang="ts">
const counter: Ref<number> = useState('counter', () => 500)
</script>
```

## テキストボックスからの値の変更

以下のように　`app.vue` を修正します。

```vuejs:app.vue
<template>
  <div>
    Counter: {{ counter }}
    <button v-on:click="counter++">
      +
    </button>
    <button v-on:click="counter--">
      -
    </button>
  </div>
  <div>
    <input type="number" v-model="inputNumber" ref="hoge"/>
    <button v-on:click="onClickButton" style="background-color: grey">
      設定
    </button>
  </div>
</template>

<script setup lang="ts">
const counter: Ref<number> = useState('counter', () => 500)

const inputNumber: Ref<number> = ref(0)

const onClickButton = (e) => {
  counter.value = inputNumber.value
}
</script>
```

Counterの下に数字入力（初期値0）と設定ボタンが表示されればOKです。
処理としては、画面の状態に応じて変更される変数は `ref` によりRef型で定義していることと、
Ref型の値は `value` 属性を通じて設定ができることがわかるかと思います。
`v-model` という属性が出てきましたが、これは双方向バインディングを実現するための機構で、Ref型などのリアクティブな変数を画面操作に応じて自動的に設定するものとなります。

## `computed` と `watch` による変数変更監視

`computed` を使うと、あるリアクティブな変数に変更があった場合のみ描画変更する機能を用意することができます。

```vuejs:app.vue
<template>
  <div>
    Counter: {{ counter }}
    <button @click="counter++">
      +
    </button>
    <button @click="counter--">
      -
    </button>
  </div>
  <div>
    Double Counter: {{ doubleCount }}
  </div>
</template>

<script setup lang="ts">
const counter: Ref<number> = useState('counter', () => 500)

// computedによりcounter変数の監視が行われる
const doubleCount = computed(() => {
  return counter.value * 2
})
</script>
```

例えば、上記の例では doubleCountの値はcounterの値に変更が発生するたびに2倍の数値となるよう自動的に計算されます。
＃ `computed` の中にあるリアクティブな変数を自動的に監視します。

同様に `watch` も存在し、こちらは描画には直接影響しない副作用のみの処理を記載するのに役に立ちます。
以下の例では `counter` に変更が発生するたびにalertでcounterの数値を表示します。

```vuejs:app.vue
<template>
  <div>
    Counter: {{ counter }}
    <button @click="counter++">
      +
    </button>
    <button @click="counter--">
      -
    </button>
  </div>
</template>

<script setup lang="ts">
const counter: Ref<number> = useState('counter', () => 500)

// watchによりcounter変数の監視が行われる
watch(counter, (count, prevCount) => { alert(counter.value) })
</script>
```

## まとめ

* Nuxt3で使用するVue3について簡単な使用例について実際に動かして試すことができました。