Vueを理解する　#リアクティブシステム編

# Web系初学者がリアクティブシステムを理解する　～Vue.js～

#### 本記事について
自分なり（WEB系初学者として）の学びや気づきをまとめるノートです。
誰かの一助になれれば万々歳!!

## リアクティブシステムとは
SEをやっていてもリアクティブという聞きなれない言葉がWeb系では頻出する。
リアクティブとは 『**その値が監視され、変更が検知される状態**』 とのこと。
Vue.js公式ドキュメント（[Vue.js 公式ドキュメント　セクション：はじめに](https://ja.vuejs.org/guide/introduction.html#:~:text=%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%93%E3%83%86%E3%82%A3%E3%83%BC%3A%20Vue%20%E3%81%AF%20JavaScript%20%E3%81%AE%E7%8A%B6%E6%85%8B%E3%81%AE%E5%A4%89%E5%8C%96%E3%82%92%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%AB%E8%BF%BD%E8%B7%A1%E3%81%97%E3%80%81%E5%A4%89%E5%8C%96%E3%81%8C%E8%B5%B7%E3%81%8D%E3%82%8B%E3%81%A8%E5%8A%B9%E7%8E%87%E7%9A%84%E3%81%AB%20DOM%20%E3%82%92%E6%9B%B4%E6%96%B0%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)）にも
>リアクティビティー: Vue は JavaScript の状態の変化を自動的に追跡し、変化が起きると効率的に DOM を更新します。

という記載となっている。

##### 状態の変化を自動的に追跡？効率的にDOMを更新？
この自動的に追跡する（監視し検知）というのが見えづらく理解に時間がかかったので、この部分についてから前提知識として入れていく。

## 監視し検知し効率よく操作する仕組み
ご存じの通りJavaScriptによって実現している。
- 『監視・検知』には`Proxy`オブジェクト
- 『効率よく操作』には`Reflect`オブジェクト
が利用されている。見えないところでこの子達が頑張ってリアクティブシステムが実現されている

##### 『監視対象』
以下のような対象を監視することが可能

- **オブジェクトのプロパティ**： オブジェクトの各プロパティの変更
- **配列の要素**： 配列の要素の追加、削除、変更
- **プリミティブなデータ**： 数値や文字列などの単一の値

:::note info
JavaScriptにおけるオブジェクトとは？
**キーと値のペア**でデータを管理する構造体またはメソッドを保持する複数のプロパティによって構成されている。
基本オブジェクトと今後出てきたらキーバリューやメソッドを持ってるんだと覚えておく！
:::

注意としては、
Javaのようなクラスタイプである場合全て **「関数＝メソッド」** として考えることができるが、Javascriptにおいてはメソッドと関数は明確に別で
- **メソッドはオブジェクト内にて定義する** 
- **関数はオブジェクトとは独立して存在する** 

それぞれ用途が異なるので混在しないこと！(私はこれを理解できていなかった…)
では上記を踏まえたうえでVueにおいてどのようにリアクティブシステムを実現されるか見ていく!!

## Vueにおけるリアクティブシステム
ヒジョーに便利なこと、Vueでは監視し、検知し、DOMを更新する仕組みがそもそも備わっている!!
なので我々はVueに検知してほしいオブジェクトを定義するのみなのです。
`data()`メソッドか`ref()／reactive()`メソッドを使用し定義することができます。
これはそれぞれ　**Vueが提供している2つのAPIスタイル** に準拠している。
1. Options API `data()`
2. Composition API `ref() や reactive()`



### `data()`の説明
**仕様**
データバインドというコンポーネントが持つ状態（ステート）を宣言するための特殊なメソッドでVueが提供しているOptions APIスタイルでの記法。オブジェクト指向に近くJavaを知っているSEの私としてはそれほどコード自体への取っつきづらさのようなものはないので良い。

#### data()での書き方（Typescriptを使用しています。）
```vuejs
<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  data() {
    return {
      count: 0 as number, //data()内にcountを定義しリアクティブな変数とする
    };
  },
  methods: {
    increment() {
      this.count++; // メソッドでcountを増加
    },
  },
});
</script>

<template>
  <!-- リアクティブとして定義されたcountのDOMを効率よくVueが更新 -->
  {{ count }}
  <button @click="increment">Count</button>
</template>
```
###### ↓画面表示↓
![chrome-capture-2024-9-28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886833/85f92237-8ab3-7738-8f80-d10e29e05383.gif)

### `ref()／reactive()`の説明
**仕様** 
Composition APIスタイルでの記法。scriptに`setup`属性を付与しVueに「リアクティブシステムとして見てね」と教えます。この中でrefやreactiveメソッドを使用し変数へ定義することでリアクティブなデータとして扱うことができる。
- ref：プリミティブなデータ型（数値、文字列、ブーリアンなど）に使用
- reactive：複雑なデータ（オブジェクト、配列など）に使用

#### ref()での書き方（Typescriptを使用しています。）
```vue
<script setup lang="ts">
import { ref } from "vue";

// `ref`を使ってリアクティブな数値型のカウントを定義
const count = ref<number>(0);
</script>

<template>
  {{ count }}
  <button @click="count++">Count</button>
</template>
```

個人的にはdataメソッドを使用した方が理解はしやすいかなと感じた。
（困ったら公式ドキュメント見てね　[Options API は Composition API どちらを選ぶか？](https://ja.vuejs.org/guide/introduction#which-to-choose)）


## まとめ
今回記事を書くにあたって、リアクティブといった概念からSEとして慣れ親しんでいるJavaとの比較といったところをできたと思う。こちらがやるべきこととVueがやってくれるところの境目もかなり曖昧だったのでよかった。
やっぱりアウトプットは大事。（つよつよエンジニアの皆様間違っていれば指摘ください！）
これからも少しずつ続けていきたいと思う。個人開発や環境構築なども今後は載せていきたいな！

では、また！