Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vue.jsリアクティブを 深堀りしてみる

kamoshita_keisuke
April 25, 2024
54

Vue.jsリアクティブを 深堀りしてみる

Vue.jsのりアクティブの仕組みについて解説しました

kamoshita_keisuke

April 25, 2024
Tweet

Transcript

  1. 同じことをプログラムに起こしてみる let A1 = 1 let A2 = 2 let

    A3 = A1 + A2 console.log(A3) // 3 A1 = 2 console.log(A3) // 3 のまま スプレッドシートと同じ手順をプログラムに書いても動かない
  2. 同じことをプログラムに起こしてみる let A1 = 1 let A2 = 2 let

    A3 = A1 + A2 console.log(A3) // 3 A1 = 2 A3 = A1 + A2 // A3の更新処理 console.log(A3) // 4 もう一度更新処理を呼び出すことで更新される
  3. 同じことを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 に更新される
  4. はじめに宣言があります A1が更新されると 宣言的な方法で変化に対応できるようにする A1.value = 2 自動で更新処理が実行される () => A1.value

    + A2.value 変更に反応 副作用(エフェクト) これがリアクティビティ const A1 = ref(1) const A2 = ref(2) const A3 = computed(() => A1.value + A2.value)
  5. 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) 依存関係
  6. 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
  7. 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
  8. ref/reactiveの実装 function ref(value) { const refObject = { get value()

    { track(refObject, 'value') return value }, set value(newValue) { value = newValue trigger(refObject, 'value') } } return refObject }
  9. 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という
  10. 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という
  11. リアクティビティのデバッグ 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 } })