Composition APIとは
Vue.jsの3系から導入された、新しいコンポーネント作成手段です。
React Hooksのように、ロジックや状態を切り出すことを可能にします。
一方、従来からあるSFCファイルにコンポーネントの見た目/状態/ロジックをまとめて記述する作成手段をOptions APIと言います。
Options APIはコードをまとめて書けるが故に、それ以上分割できない不便さがありました。
Composition APIではロジックや状態に関するコードを切り出すことができるため、Options APIの不便さを解消できます。
また、見た目に関するコードとは別々に管理されることにより、ロジックの再利用性が高まります。
とはいえComposition APIはOptions APIを代替えしたり非推奨とするわけではなく、使い分けることが可能です。
Composition APIは、コンポーネント間で状態やロジックを共有する必要がある大規模なアプリケーション開発に向いています。
サンプル
以下のかんたんなアプリをComposition APIで作成しました。
- 名前を入力できる
- 数値の増減ができる
- これらがリアクティブに反映される
以下のような役割です。
-
Main.vue
:名前と数値を入力するコンポーネント、他のコンポーネントを呼び出している -
Score.vue
:数値を表示するコンポーネント -
JudgeName.vue
:名前を表示するコンポーネント -
use-judge.js
:値の状態、数値の増減のロジックを切り出したファイル
<template>
<div>
<p>審査員名を入力</p>
<input type="text" v-model="state.judgeName" />
<p>得点を設定</p>
{{ state.score }}
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<div class="body">
<Score />
<JudgeName />
</div>
</template>
<script>
import { provide } from "vue";
import Score from "./Score.vue";
import JudgeName from "./JudgeName.vue";
import { useJudge } from "../functions/use-judge.js";
export default {
components: {
Score: Score,
JudgeName: JudgeName,
},
setup() {
const { state, increment, decrement } = useJudge();
provide("inputState", state);
return {
state,
increment,
decrement,
};
},
};
</script>
<style scoped>
省略
</style>
<template>
<div class="score">
<p class="text" :class="{ low: state.score < 90 }">
{{ state.score }}
</p>
</div>
</template>
<script>
import { inject } from "vue";
export default {
setup() {
const state = inject("inputState");
return {
state,
};
},
};
</script>
<style scoped>
省略
</style>
<template>
<div class="judgeName">
<p class="text">
{{ state.judgeName }}
</p>
</div>
</template>
<script>
import { inject } from "vue";
export default {
setup() {
const state = inject("inputState");
return {
state,
};
},
};
</script>
<style scoped>
省略
</style>
import { reactive } from "vue";
export const useJudge = () => {
const state = reactive({
score: 89,
judgeName: "山田"
});
const increment = () => {
if (state.score >= 100) return;
state.score++;
};
const decrement = () => {
if (state.score <= 0) return;
state.score--;
};
return {
state,
increment,
decrement
};
};
setup関数
Composition APIではsetup関数内にデータやメソッドなどを設定します。
設定したものをreturnし、template内で使用する、という流れになります。
状態とロジックの切り出し
今回はuse-judge.js
というファイルで状態とロジックを切り出しています。(state,increment,decrement)
これらはMain.vue
で使用しています。
const { state, increment, decrement } = useJudge();
この記述によって、Main.vue
内でstate,increment,decrementを使用できます。
リアクティブなデータ
今回のアプリでは入力された名前と数値をリアクティブに反映させています。
Composition APIでリアクティブなデータを扱いたい場合、ref
とreactive
という方法が用意されています。
use-judge.js
で、reactive
を用いてscoreとjudgeNameを定義しています。
Provide/Inject
3系特有のものではありませんが、Provide/Inject
についても紹介します。
use-judge.js
でstateを定義し、Main.vue
で使用しています。
このstateを表示させるには、Score.vue
とJudgeName.vue
にstateを共有する必要があります。
これを実現しているのが、Provide/Inject
です。
まずは他のコンポーネントに共有したい値をProvideに渡します。
provide("inputState", state);
左側がキー名、右側が共有したい値です。
続いてInjectを使用して、Provideに設定された値を取得します。
const state = inject("inputState");
Provideに設定されたキー名をInjuctに指定することで、値を取得できます。
参考