Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Vue.jsリアクティブを 深堀りしてみる
Search
kamoshita_keisuke
April 25, 2024
0
82
Vue.jsリアクティブを 深堀りしてみる
Vue.jsのりアクティブの仕組みについて解説しました
kamoshita_keisuke
April 25, 2024
Tweet
Share
Featured
See All Featured
KATA
mclloyd
30
14k
Bash Introduction
62gerente
613
210k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
Making the Leap to Tech Lead
cromwellryan
134
9.4k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.6k
For a Future-Friendly Web
brad_frost
179
9.8k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.7k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
A designer walks into a library…
pauljervisheath
207
24k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Transcript
Vue.jsリアクティブを 深堀りしてみる 2024/4/23 UV Study : Vue.js LT会
自己紹介 名前:鴨下啓佑 所属:ユニークビジョン株式会社 Vue.jsとTypescriptのフロントエンド開発が得意分野ですが、最近はあまりフロ ント開発はできていない。 今回はVue.jsのコアな部分について話します
そもそもリアクティブってなに?
リアクティビティってなに? リアクティビティーとは、 宣言的な方法で変化に対応できるようにする プログラミングパラダイムです Vue.js 公式ドキュメントより
リアクティビティってなに? スプレッドシートを例に見てみます A1を2に 変更する A3が自動的に更新される
同じことをプログラムに起こしてみる let A1 = 1 let A2 = 2 let
A3 = A1 + A2 console.log(A3) // 3 A1 = 2 console.log(A3) // 3 のまま スプレッドシートと同じ手順をプログラムに書いても動かない
同じことをプログラムに起こしてみる let A1 = 1 let A2 = 2 let
A3 = A1 + A2 console.log(A3) // 3 A1 = 2 A3 = A1 + A2 // A3の更新処理 console.log(A3) // 4 もう一度更新処理を呼び出すことで更新される
これをWebページに置き換えてみると おびただしい数の変数の制御 function updateField1() { field1 = 'update1' render() }
function updateField2() { field2 = 'update2' render() } …
これをWebページに置き換えてみると おびただしい数の変数の制御 画面に表示している大量の変数との 同期を常に考えなければいけなくなる
これを解決してくれるのが リアクティビティ というパラダイム
同じことをVue.jsのリアクティブで表現 const A1 = ref(1) const A2 = ref(2) const
A3 = computed(() => A1.value + A2.value) console.log (A3.value) // 3 A1.value = 2 await nextTick() // 更新を待つ console.log (A3.value) // 4 に更新される
はじめに宣言があります A1が更新されると 宣言的な方法で変化に対応できるようにする A1.value = 2 自動で更新処理が実行される () => A1.value
+ A2.value 変更に反応 副作用(エフェクト) これがリアクティビティ const A1 = ref(1) const A2 = ref(2) const A3 = computed(() => A1.value + A2.value)
A1 = ref(1) A2 = ref(2) A3 computed(() => A1.value
+ A2.value) A1, A2の購読者(サブスクライバー) const A1 = ref(1) const A2 = ref(2) const A3 = computed(() => A1.value + A2.value) 依存関係
Vue.jsのリアクティビティの仕組み Vue.jsって、変数のセットに対して自動で処理を行ってくれますよね? これはどうやって実現されているか?
Javascriptのプロパティ傍受 Javascriptでプロパティへのアクセスを傍受する手段は主に2つ あります • getter / setter • Proxy
Javascript getter / setter const obj = { _value: 0,
get value() { console.log('call get method'); return this._value; }, set value(newValue) { console.log('call set method'); this._value = newValue; } } obj.value = 1; // call set method console.log(obj.value); // call get method // 1
Javascript Proxy const obj = { value: 1 } const
proxyHandler = { get(target, key) { console.log('call proxy get') return target[key] }, set(target, key, value) { console.log('call proxy set') return target[key] = value } } const proxy = new Proxy(obj, proxyHandler) proxy.value = 2 // call proxy set console.log(proxy.value) // call proxy get // 2 console.log(obj.value) // 2
ref/reactiveの実装 • getter / setter ◦ → refオブジェクトの実装 • Proxy
◦ → reactiveオブジェクトの実装
ref/reactiveの実装 function ref(value) { const refObject = { get value()
{ track(refObject, 'value') return value }, set value(newValue) { value = newValue trigger(refObject, 'value') } } return refObject }
Vueのリアクティブの仕組み target key effects A1 value [() => A1.value +
A2.value] A2 value [() => A1.value + A2.value] A3の定義元 computed(() => A1.value + A2.value) 購読リスト[WeakMap] getterが呼ばれると購読リスト に登録する console.log(A3.value) ※templateでの参照も同様 これをTrackという
Vueのリアクティブの仕組み setterが呼ばれると購読リストから effectsを取得して登録されている effectを実行する A1.value = 2 target key effects
A1 value [() => A1.value + A2.value] A2 value [() => A1.value + A2.value] 購読リスト[WeakMap] target key effects A1 value [() => A1.value + A2.value] これをTriggerという
リアクティビティのデバッグ Vue.jsにはTrackとTriggerのフックが用意されています Playground // コンポーネントのフック onRenderTracked((event) => { debugger })
onRenderTriggered((event) => { debugger }) // computedのフック const plusOne = computed(() => count.value + 1, { onTrack(e) { // count.value が依存関係として追跡されたときにトリガーされます debugger }, onTrigger(e) { // count.value が変更されたときにトリガーされます debugger } })
reactiveオブジェクトの制限 reactiveオブジェクトにいくらかの制限があるのですが、 reactiveの実態がProxyであるためによるものです。 • オブジェクト型しか使えない ◦ Proxyはオブジェクト型にしか使えない • オブジェクト全体を置換できない ◦
サブスクライブしているインスタンス自体が変わるため • 分割代入できない ◦ オブジェクトからプロパティを参照しないとProxyのフックが呼ばれない
まとめ • refオブジェクトはgetter/settersで実装されている • reactiveオブジェクトはProxyで実装されている • Track(getter)されると購読リストに登録にエフェクトが 登録される • Trigger(setter)されると購読リストに登録されたエフェ
クトが実行される
参考 リアクティビティーの探求 https://ja.vuejs.org/guide/extras/reactivity-in-depth.html