Composition APIを利用したロジックの共通化
Composition APIでは、JavaScriptの標準的な記法でデータ/メソッド/算出プロパティなどを記述できるため、ロジックの共通化が容易です。例えば、iOSとAndroidで共通の処理内容を、リスト8の通り切り出せます。リスト8のPhonesLogicメソッドでは、受け取った引数でデータの初期値を設定し、メソッドや算出プロパティと合わせて返却します。
import { reactive, computed, toRefs } from 'vue'
export default function PhonesLogic(initialList) {
// reactiveでデータを記述
const state = reactive({
terminals: initialList,
newTerminal: ''
})
// メソッド
function addNew() {
state.terminals.push(state.newTerminal)
state.newTerminal = ''
}
// 算出プロパティ
const count = computed(function () {
return state.terminals.length
})
// ここまで定義してきた内容を返却
return {
...toRefs(state), addNew, count
}
}
リスト8の共通ロジックを利用するコンポーネントの実装はリスト9です。(1)でiOS/Androidの各処理を行うロジックを生成し、(2)で総端末数の算出プロパティを定義後、(3)で各ロジックと算出プロパティをまとめてreturnします。
setup() {
// PhoneLogicでiOS/Androidの各処理ロジックを生成 ...(1)
const iOSLogic = PhonesLogic(['iPhone 11'])
const androidLogic = PhonesLogic(['Galaxy S20 5G'])
// 総端末数を計算する算出プロパティ ...(2)
const countTotal = computed(function() {
return iOSLogic.count.value + androidLogic.count.value
})
// ここまで定義してきた内容を返却 ...(3)
return {
iOSLogic, androidLogic, countTotal
}
}
応用的なトピック:プロパティとライフサイクルフック
以下では応用的なトピックとして、プロパティとライフサイクルフックをComposition APIで記述する方法を、図2のサンプルで説明します。このサンプルでは、プロパティで機種名/メーカー/重量を設定できるコンポーネントを表示します。コンポーネントがWebページに追加(マウント)された時のライフサイクルフックでログを出力します。
Options APIで記述したコンポーネントはリスト10です。(1)のpropsで、String型のname(機種名)とvendor(メーカー)、Number型のweight(重量)プロパティを設定します。(2)ではvendorとnameを結合して取得する算出プロパティfullNameを記述していますが、プロパティ値を取得するには(3)の通り「this.<プロパティ名>」とします。(4)はコンポーネントの追加(マウント)時に実行されるmountedライフサイクルフックです。
<template>
<div class="one-phone">
<h3>{{ fullName }}</h3>
<div>機種名:{{ name }}</div>
<div>メーカー:{{ vendor }}</div>
<div>重量:{{ weight }}g</div>
</div>
</template>
<script>
export default {
// プロパティの設定 ...(1)
props: {
name: String,
vendor: String,
weight: Number
},
// 算出プロパティ ...(2)
computed: {
fullName() {
// thisでプロパティを参照 ...(3)
return this.vendor + ':' + this.name
}
},
// mountedライフサイクルフック ...(4)
mounted() {
console.log('コンポーネントがマウントされました')
}
}
</script>
同じコンポーネントをComposition APIで記述した<script>部はリスト11となります。<template>部はリスト10と同一です。
export default {
// プロパティの設定 ...(1)
props: {
name: String,
vendor: String,
weight: Number
},
// setupメソッドの引数propsにプロパティが含まれる ...(2)
setup(props) {
// 算出プロパティ ...(3)
const fullName = computed(function() {
// propsでプロパティを参照 ...(4)
return props.vendor + ':' + props.name
})
// onMountedライフサイクルフック ...(5)
onMounted(function() {
console.log('コンポーネントがマウントされました')
})
return {
fullName
}
}
}
プロパティ設定(1)の記述はリスト10と同一です。setupメソッド(2)の引数propsにプロパティ値が含まれるため、fullName算出プロパティ(3)でプロパティ値を参照するには(4)の通り「props.<プロパティ名>」とします。
ライフサイクルフックは(5)の通り、処理内容のfunctionをonMountedメソッドの引数に与えて記述します。なおVue 3では、利用できるライフサイクルフックがVue 2から細かく変更されています。詳細はComposition APIのドキュメントを参照してください。
まとめ
本記事では、Vue.jsの次期バージョン「Vue 3」で導入される新機能のうち、新しいコンポーネント記述形式であるComposition APIについて説明しました。コンポーネント機能の実装が分散したり、再利用が難しかったりするといった、従来のコンポーネント記述形式(Options API)が抱える問題点を、Composition APIを利用して解決できます。Composition APIの利点を生かしてロジックを共通化する例を、記事内で紹介しました。
次回は、Vue 3に導入されるComposition API以外の新機能を紹介していきます。
