Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Vue.jsリアクティブを 深堀りしてみる
Search
kamoshita_keisuke
April 25, 2024
0
96
Vue.jsリアクティブを 深堀りしてみる
Vue.jsのりアクティブの仕組みについて解説しました
kamoshita_keisuke
April 25, 2024
Tweet
Share
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
36
6.2k
It's Worth the Effort
3n
187
29k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
KATA
mclloyd
PRO
32
15k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
700
Rebuilding a faster, lazier Slack
samanthasiow
84
9.3k
A designer walks into a library…
pauljervisheath
210
24k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
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