なぜ、Vue Composition APIを使うのか、理解する【メリット/デメリットまとめ】

## はじめに

**Vue3のリリース**が迫ってきました。
順調に行けば、**公式リリースは8月上旬**のようです。楽しみですね。

> Our current target dates are mid July for the RC (release candidate) and early August for the official release of 3.0.
https://github.com/vuejs/rfcs/issues/183

Vue3の**目玉の機能**として、**「Composition API」**があります。

この記事では、**「”なぜ” “なんのために” Composition APIを使うのか」**理由について、まとめています。

「Composition APIの使い方」についての説明は、この記事では割愛します。

以下の記事に、具体的なComposition APIの使い方とProviderパターンについて記述しました。
本記事と合わせて御覧ください。

Vue3 Composition APIにおいて、Providerパターン(provide/inject)の使い方と、なぜ重要なのか、理解する。
https://qiita.com/karamage/items/4bc90f637487d3fcecf0

## Composition APIを使う理由、なんもわからん

![dog3_1_question.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/045ee205-7372-a004-0bf2-24517aaaf175.png)


これまで、私自身、**Composition APIを使う理由**が、**よくわかっていません**でした。

なんとなく、**「setup関数でまとめて処理を登録しておく」**くらいのことを**雰囲気で**理解していました。

「Composition APIで書くほうが**イケてるし、カッコいい**(重要)」くらいの**ノリ**で

何のために使うのか、**メリットがよく分からない状態**でした。

![62783026-810e6180-ba89-11e9-8774-e7771c8095d6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/7b03333f-3584-3359-9c10-ba579cc7cb0a.png)


Composition APIについて調べていると、**↑の図、よく見ませんか？**

既存APIとComposition APIのコードを比較して、メリットを提示しているようですけど

私は

「**そんなに違わない**ように見える」

「**違いがよくわからん**」

っといった感想を持ちました。

私と同じように

「Vueに新しく、Composition APIってのが出るらしいけど、**なんとなく**使おうかな〜」

「でも、**なんのために使うんだっけ**」

と思っている方が多いのではないかなと考え、この記事を執筆しています。

この記事が、誰かのお役に立てれば幸いです。

## Composition API RFC を読んだら、「なぜ、使うのか」を理解した

先日 @shwld が主催した

**「Vue Composition APIを知る会」**

で、**Composition APIのRFCを読む機会**があり、そこで改めて「**”なぜ”** Composition APIを使うのか」理解することができました。

![IMG_0559.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/c40cf89a-cc57-7427-d79d-1f7cbb8e0c1d.jpeg)


**Composition APIの公式の説明資料**として、以下のページにRFCがあります。
Composition API (https://vue-composition-api-rfc.netlify.com)

↑を読むと、「”なぜ” Composition APIを使うのか」**答え**が書いてありました。

以下にRFCに書いてある内容をまとめます。

## Composition APIとは

Composition APIは、
ロジックを**合成関数(composition function)**に**カプセル化**することで、コンポーネント間での**ロジックを再利用を可能**にするAPIです。
(React HooksのVue版みたいなもの)

「Composition」は、**「構成(すること),組み立て(ること)」**という意味。

サンプルコード

```vue
<template>
  <button @click="increment">
    Count is: {{ state.count }}, double is: {{ state.double }}
  </button>
</template>

<script>
import { reactive, computed } from 'vue'

export default {
  setup() {
    const state = reactive({
      count: 0,
      double: computed(() => state.count * 2)
    })

    function increment() {
      state.count++
    }

    return {
      state,
      increment
    }
  }
}
</script>
```

Vueの作成者である**Evan You**氏いわく、**Composition APIを提案する背景となった動機**について、次のように説明しています。
> 論理合成(logic composition)は、**プロジェクトをスケールアップ**する場合には、おそらく**最も深刻な問題のひとつ**です。さまざまなタイプのプロジェクトを扱うユーザは、さまざまなニーズに直面します。その中には、オブジェクトベースのAPIを使用して簡単に処理できるものと、できないものがあります。主な例としては、
1. **複数の論理タスクをカプセル化**した、**大規模な**(数百行の)コンポーネント
2. 複数のコンポーネント間においてタスクに**ロジックを共有する**ニーズ

https://www.infoq.com/jp/news/2019/10/vue3-function-based-api-rfc/ より引用

## ”なぜ” Composition APIを使うのか

**結論**から言いますと、

**「”なぜ” Composition APIを使うのか」**

その**理由**は、

**「ロジックの抽出と再利用」をするため**です。

(他にも「TypeScript 型強化」などが理由として挙げられますが、この記事では割愛します)

![daiku_nokogiri_kiru.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/6075be01-0fea-925b-4efb-f6da697fcb5e.png)


### ロジックの抽出と再利用

「ロジックの抽出と再利用」は、**なぜ**するのか。

「ロジックの抽出と再利用」が必要な理由は、
**複雑に肥大化したコンポーネント**を、**小分けにして関心事で分別**し、**クリーンな状態に整理**するためです。

近年、Vue を使用して**大規模な**プロジェクトを構築することが増えました。

**肥大化してメンテしにくい**コンポーネントを目の当たりにして、我々エンジニアが**苦しむ**ことも増えました。

![character_program_fat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/fcb9d770-b4c2-cb0f-dda6-a64970415079.png)


肥大化したコンポーネントのコードは、**依存関係が複雑で量も多く**、**コードを読むこと自体難しく**なります。

これまでのVue2.xでは、**「複数のコンポーネント間でロジックを抽出して再利用するためのクリーンでコストのかからないメカニズム」が欠如**していました。

Vue2.xでは、コンポーネントをSFCファイルに記述します。
SFCファイルに、コンポーネントのView/状態/ロジックをまとめて閉じ込めて記述することができて便利ですが、**これ以上は分割ができないという欠点**がありました。

**これを解決するのが、Composition APIです。**

Composition APIによって、コンポーネントの**コードを整理**する際に、開発者に**より高い柔軟性を提供**します。
コンポーネント間で、**ロジックや状態を抽出して再利用することが、簡単**になります。

**SFCに記述するのはViewの見た目に関することだけ**にして、**ロジックや状態を外部に切り出せる**ようになるのです。

![game_ken_seiken.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/6d47d726-d31d-20b6-6e93-7e4b0f32922c.png)


つまり、Composition APIは、肥大化したコンポーネントを**小さく切り刻むための聖剣**なのです。

Composition APIを使って「ロジックを抽出して再利用する」具体的なやり方について、以下の記事が参考になります。

> vue-composition-apiを使って機能単位のコード分割と合成を試してみた
https://qiita.com/s_nagasawa/items/ef70032f996face318e5

**逆に言えば**、100行にも満たないような**小さなコンポーネント**をComposition APIで書き直しても、あまり**メリットを享受できない**です。
もし小規模〜中規模なVueプロジェクトにおいて、現状のVue2.xベースのコードでコンポーネントの肥大化に**苦しんでいない**のであれば、Composition APIで書き直しても**コスパが悪い**ので**やめておいたほうがよいのでは**ないかなと思います。
(**新規プロダクト**で、最初から全部Composition APIで書くのは**あり**だと思います)

### mixinは、使えない?

Vue2.xのロジックの再利用の仕組みとして、「mixin」があります。
しかし、「mixin」には、**罠が多く**あり、今では「mixin」を使うことは**アンチパターン**という認識です。
**極力「mixin」は使わない**ようにしましょう。

![nezumi_tori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/d433d07c-4574-5d93-5408-44c5b74e92d6.png)


なぜmixinがアンチパターンなのかについては、下記の記事に詳しく書かれてあります。

> 俺がやらかしたVue mixinのアンチパターンから学ぶmixinの使い方と代替案
https://aloerina01.github.io/blog/2018-12-25-1

## Composition APIを使う際のデメリット

ここまでの説明で、Composition APIを使うメリットは、理解できたかと思います。

じゃあ、**デメリットはないのか?** 

**あります。**

デメリットを一言でいうと、**「自由すぎ」**です。

Composition APIによって、**自由に**ロジックを切り出せるようになりますが、一方で、いままで**Vueが暗黙的に行ってくれていたレールから外れる**ことを意味します。

今までは、何となくコンポーネントを**SFCファイルに記述して、状態管理をVuexに任せておけば、何とかなっていた**のですが、それが**根本からガラッと大幅に変わります。**

Composition APIによって、Vueの世界と外の世界に**任意の境界線**を引き、モジュールに切り分けて、どれとどれを結合するかを、自由に「設計」できるようになります。
しかしながら、どういう単位でロジックやモジュールを切り出したり、共通化したり、といった疑問に対して、**明確な正解がない**のです。
Composition APIの**ベストプラクティス**を今決めるのは**時期尚早**であり、**手探り**で進める必要があります。

つまり、**Vueが管理している壁の中の世界**から、**壁の外の無秩序な荒野**へと放り出されるのです。

**無秩序な**荒野で、**テキトーに**開発していると、隠れていた猛獣に襲われたり、食料が尽きたりといった**致命的なアクシデント**に見舞われます。**計画的に**外の世界を開拓しないと**危険がいっぱい**なのです。

人柱になりたくない方は、**「様子見」**という選択も、アリだと思います。

### 「設計」や「アーキテクチャ」が重要になる

その荒野に秩序を与えるのは、我々、調査兵団(エンジニア)の**「設計」**です。

![map_takara_chizu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/374e1863-51b2-7128-f74d-e3f3fd26a012.png)


今後は、**「アーキテクチャ」**が重要になります。

**つまり、Composition APIを使用するデメリットは、ちゃんと「設計」や「アーキテクチャ」を考えなければならないこと**です。

**学習コストも、高い**です。

例えば、「クリーンアーキテクチャ」を理解して、実装していくことが求められます。

![20190708031020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93703/0986efac-8515-4aa8-9572-cd3e4531a58d.png)


>実装クリーンアーキテクチャ
https://qiita.com/nrslib/items/a5f902c4defc83bd46b8

「Vueの中の世界」と「外の世界」の**境界線**を意識して、**自由への翼**を獲得しましょう。

## まとめ

・https://vue-composition-api-rfc.netlify.com を読もう。

・Composition APIを使う理由は、**「ロジックの抽出と再利用」**のため。(TypeScriptの型強化の側面もあり)

・肥大化したコンポーネントを、**小さく切り刻むための聖剣**だと理解した。(mixin、お前はダメだ)

・聖剣ですので、使いこなすには、**それなりの熟練度が必要**。レベル１の村人が装備すると怪我をする恐れもあり。

・もともと小さいコンポーネントをCompositon APIで書き直しても、**あまりメリットはない**。

・今後はちゃんと**「設計」**や**「アーキテクチャ」**を考えなければならない。

## Composition API リンク集

Composition API RFC
https://vue-composition-api-rfc.netlify.com

API Reference
https://composition-api.vuejs.org/api.html

Composition API Demo
https://github.com/LinusBorg/composition-api-demos

vue-composition-apiを使って機能単位のコード分割と合成を試してみた
https://qiita.com/s_nagasawa/items/ef70032f996face318e5

俺がやらかしたVue mixinのアンチパターンから学ぶmixinの使い方と代替案
https://aloerina01.github.io/blog/2018-12-25-1

実装クリーンアーキテクチャ
https://qiita.com/nrslib/items/a5f902c4defc83bd46b8

【Vue3に備える】実務で使うComposition APIについて考える
https://medium.com/finatext/composition-api-for-vue3-63631dbadcef

先取りVue 3.x !! Composition API を試してみる
https://qiita.com/ryo2132/items/f055679e9974dbc3f977

Vue Composition API v1-beta で使えるリアクティブ関連のAPI一覧
https://qiita.com/ryo2132/items/6dc51ede8082dea75812

Vue Composition API を使ったストアパターンと TypeScript の組み合わせはどのくらいスケールするか？
https://qiita.com/tmy/items/a545e44100247c364a71

Composition API 勘所など
https://webneko.dev/posts/notices-of-composition-api-in-vue3-eve

Vue.jsのcomposition-apiにおける"ref"と"reactive"って何が違うの？
https://qiita.com/mgr/items/a5e35636d371969e0a4d

【Vue.js】Composition API時代の便利ライブラリ「VueUse」を使ってみた
https://qiita.com/mascii/items/558c7d5d5bf82eaa59a6

VueUse
https://github.com/antfu/vueuse