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
81
Vue.jsリアクティブを 深堀りしてみる
Vue.jsのりアクティブの仕組みについて解説しました
kamoshita_keisuke
April 25, 2024
Tweet
Share
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
53
7.7k
4 Signs Your Business is Dying
shpigford
184
22k
Documentation Writing (for coders)
carmenintech
72
4.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
8
680
What's in a price? How to price your products and services
michaelherold
246
12k
How to train your dragon (web standard)
notwaldorf
94
6.1k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Statistics for Hackers
jakevdp
799
220k
Done Done
chrislema
184
16k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.4k
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