Vueの基本であるリアクティビティーを理解したい
リアクティブ
まずはざっくり理解するところ
・値が変更があったときに、画面に表示される内容も変更される
・画面に表示される内容が変更されたら、値も変更される
ユーザーからすれば当たり前すぎることですが、Vueはリアクティブで実現できます。ありがたい・・・
サンプル
今回はリアティブを支えるrefとreactiveについて、簡易なサンプルコードで以下の点を試してみました
・ref()とreactive()にプリミティブ値を使ってみる
・ref()とreactive()にオブジェクト値を使ってみる
・ref()をreactive()に使ってみる
検証結果
サンプルコードで試した結果、次のような結果が得られました。
・ref()にはプリミティブ値もオブジェクト値も使える
・reactive()にはプリミティブ値を入れても、きちんとリアクティブにならない。(遅延して値は反映される。この点は、なぜ??)
・ref()にオブジェクト値を入れても、template側はvalueが不要になるのでreactive()と同じ使用感になる。(勿論script側ではvalueが必要)
・reactive()のオブジェクトにref()を入れると、お互いが更新される。(reactive.xxxでもref.valueでもお互いが更新される)
・reactive()にref()を入れても、valueは不要(勝手アンラップしてくれる。)
以上を踏まえるとref()とreactive()の関係は、ref()はvalueというkeyにした値をreactive()にしているイメージ。
まだまだ曖昧なので少し裏側のソースコードも覗いてみます。
裏側のソースコード
こちらVueのリアクティブ部分のソースコードリンクです。
https://github.com/vuejs/core/blob/main/packages/reactivity/src/ref.ts#L124
https://github.com/vuejs/core/blob/main/packages/reactivity/src/reactive.ts#L406
今回は、ざっくりref()のソースコードを追ってみたいと思います。
内部ではcreateRef()でref()を作っているっぽいので、次はcreateRefを見てみます。
createRef()は RefImpl()を生成しているので、次はRefImplを見てみます。
RefImplはgetterとsetterでvalueの取得(trakRefValue)と更新(triggerRefValue)をしています。
この先のtrackとtriggerでDOMへ反映する処理(Effect)があるっぽいので、後日改めて追ってみたいです。
もう一点、this._valueはtoReactive()にも流れているので、こちらを見てみます。
toReactiveですが、どうやらvalueの値がオブジェクト値か判定してオブジェクト値ならreactive()に入れています。
なのでref()にオブジェクト値を入れてもリアクティブだったのは、この処理が理由でした。
公式ガイドでは、Proxy はリアクティブオブジェクトに、getter / setters は ref に使用。と言及されていますが、
この点はもう少し理解したいです。
https://ja.vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue
今回はリアクティブの表面を少しだけ覗いてみましたが、裏側の処理も追いかけていくと勉強になりました。
refとreactiveが互いに独立の機能ではなく、お互いが密接に関係している機能であることも伺えました。
リアクティブについては、今後もサクッとコードを書いて試したり、ソースコードの理解をしていきたいと思います。