Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Vue.jsリアクティブを 深堀りしてみる
Search
kamoshita_keisuke
April 25, 2024
0
98
Vue.jsリアクティブを 深堀りしてみる
Vue.jsのりアクティブの仕組みについて解説しました
kamoshita_keisuke
April 25, 2024
Tweet
Share
Featured
See All Featured
Making Projects Easy
brettharned
120
6.5k
Scaling GitHub
holman
464
140k
A better future with KSS
kneath
240
18k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
310
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
140
Music & Morning Musume
bryan
46
7k
For a Future-Friendly Web
brad_frost
180
10k
sira's awesome portfolio website redesign presentation
elsirapls
0
89
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
Getting science done with accelerated Python computing platforms
jacobtomlinson
0
76
Agile that works and the tools we love
rasmusluckow
331
21k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
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