技術とかの雑なToday I Learnedメモ

昨日に続いてComposition APIでロジックを切り離すことの整理をした

昨日に続いて Composition API でロジックを切り離すことを考える

やっていたタスクで色々悩んだり理解不足を痛感したことをここ数日投稿していたんだけど、ほんの少しだけ分かってきたのでこの数日間の内容と被ることも多いかもしれないがメモしておく。

ビューとロジックを分離する

そもそも Composition API を使って切り出すロジックは、ステートレスかステートフルかは関係なく、「コンポーネントではロジック置き場に置いてあるロジックをsetup内で呼び出して return するだけ」という状態を作り出すことを目的にする。

こうすることでビューとロジックという責務を分離することができて見通しがよくなるし、ロジックだけをテストすることが容易になる。

コンポーネントでは UI 表示に集中し、そこで利用するための値を、reactiverefcomputedなどを駆使して返すようにする。

ロジック部分

ロジックとして切り出した部分はhooksとかusecasesとか呼ばれることが多いっぽく、関数名はuseXxxのように use をつけることが慣習になっているっぽい。

リアクティブな変数(=state)、リアクティブに加工された値(=computed)、様々な処理を行う関数を定義する。これらをuseXxx内で return することで、呼び出し側で利用できるようにする。

useXxxを export し、利用する側でuseXxx内の変数や関数を呼び出す。

定義箇所によって global か local かが決まる。

export する関数内で定義した変数や関数(JavaScript なので関数も変数に格納するけど)は、呼び出し側でuseXxxを実行することで、呼び出し側のコンポーネントで local な値として持つ。

そのため、別のコンポーネントでuseXxxを実行しても state や computed が共有されることはなく、各コンポーネントで独立した値を持つ。

そして、export するuseXxxの外で定義した変数は global なスコープを持ち、複数箇所で呼ばれた場合は共有の state を持つ。

つまり、Options API で使われていた data や computed、methods を、useXxxの内部スコープで定義するか外部スコープで定義するかで local state か global state かを分けることができる。

その他

闇雲に global state をバチバチ定義すると複数箇所から書き換えられることが発生しバグが起きやすくなることが予想されるため、global state として定義する際はreadonlyにするといいとのこと。たしかに。

ここ最近で苦労しているのは、Options API で定義されたコンポーネントでuseXxxを使う場合にどうするかについて。

Composition API のsetupは、Options API のbeforeCreateおよびcreatedを内包している(表現があっているのか分からない)ので、Options API ではcreated内部でuseXxxを呼び出し、thisでコンポーネントに bind するというのが現状最も分かりやすく誰が見ても理解しやすい状態なのではないかという話を今日仕事でした。

useXxxを呼び出すまで data も computed も methods も空ということになるので、空の関数this.func() {}のようなものを methods に定義し、createdthis.func = funcのような感じにするしかない……?

Options API を Composition API に書き換えればそれが最適解なんだけれども、そう理想通りにもいかないのでどうすればいいか悩む。

参考

Vue.js composition-api を使った開発でおすすめしたいこと - Qiita

vue-composition-api で作るカスタム Hook 入門〜useHoge()を自作してみよう〜