Vue のリアクティブシステム / Reactivity In Vue
by
ryotah
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Vue ͷϦΞΫςΟϒγεςϜ
Slide 2
Slide 2 text
ࣗݾհ • Ryota Horiguchi • GitHub: ryotah • merpay ϑϩϯτΤϯυΤϯδχΞ
Slide 3
Slide 3 text
͢͜ͱ • Vue ͷϦΞΫςΟϒγεςϜͷҰ෦Λઆ໌ • ϦΞΫςΟϒγεςϜ => Ϟσϧͷมߋ͕DOMʹө͞ΕΔΈ
Slide 4
Slide 4 text
https://blog.thoughtram.io//angular/2016/02/22/ angular-2-change-detection-explained.html
Slide 5
Slide 5 text
ϦΞΫςΟϒͷ୳ٻ — Vue.js
Slide 6
Slide 6 text
Ұ୴αϯϓϧΛ
Slide 7
Slide 7 text
ஈͱ͔Β߹ܭֹۚΛදࣔ͢ΔΞϓϦέʔγϣϯ
price: {{ price }}
quantity: {{ quantity }}
total: {{ total }}
// js const app = new Vue({ el: '#app', data: { price: 100, quantity: 2 }, computed: { total() { return this.price * this.quantity; } } }); https://stackblitz.com/edit/vue-reactivity
Slide 8
Slide 8 text
• data • Vue ΠϯελϯεͷͨΊͷσʔλΦϒδΣΫτ • Vue Πϯελϯε͕࡞͞ΕΔͱϦΞΫςΟϒ γεςϜʹՃ͞ΕΔ • computed • Vue ΠϯελϯεʹΈࠐ·ΕΔࢉग़ϓϩύ ςΟ • ࢉग़ϓϩύςΟґଘؔʹͱ͖ͮΩϟο γϡ͞ΕΔ
Slide 9
Slide 9 text
ࠓͷΰʔϧ
Slide 10
Slide 10 text
let data = { price: 100, quantity: 2 }; let total = data.price * data.quantity; console.log(total); // => 200 data.quantity = 3; console.log(total); // => 300 ?
Slide 11
Slide 11 text
ͦͷ̍ ؔΛอଘ
Slide 12
Slide 12 text
let data = { price: 100, quantity: 2 }; // ࠶ܭࢉͰ͖ΔΑ͏ʹؔΛอଘ let target = () => data.total = data.price * data.quantity; target(); console.log(data.total); // => 200 data.quantity = 3; target(); console.log(data.total); // => 300 // https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-96.js
Slide 13
Slide 13 text
• อଘ͞ΕΔؔෳඞཁ • ґଘؔͷ͋Δ͚ؔͩΛཧ͍ͨ͠
Slide 14
Slide 14 text
ͦͷ̎ Dependency Class
Slide 15
Slide 15 text
export let target = null; export class Dep { constructor() { this.subscribers= []; } depend() { if (target && !this.subscribers.includes(target)) { this.subscribers.push(target); } } notify() { this.subscribers.forEach(sub => sub()); } }
Slide 16
Slide 16 text
let data = { price: 100, quantity: 2 }; let watcher = () => data.total = data.price * data.quantity; const dep = new Dep(); target = watcher; dep.depend(); target(); target = null; console.log(data.total); // => 200 data.quantity = 3; dep.notify(); console.log(data.total); // => 300 // https://stackblitz.com/edit/vue-reactivity-step-by-step?file=step-97.js
Slide 17
Slide 17 text
Dependency Class ͷׂ
Slide 18
Slide 18 text
https://medium.com/vue-mastery/the-best- explanation-of-javascript-reactivity-fea6112dd80d
Slide 19
Slide 19 text
https://medium.com/vue-mastery/the-best- explanation-of-javascript-reactivity-fea6112dd80d
Slide 20
Slide 20 text
https://medium.com/vue-mastery/the-best- explanation-of-javascript-reactivity-fea6112dd80d
Slide 21
Slide 21 text
• ϓϩύςΟ͝ͱʹ Dep Πϯελϯε͕ඞཁ • ґଘؔͷ͋Δ͚ؔͩΛཧ͍ͨ͠ • ʢະղܾʣ
Slide 22
Slide 22 text
ͦͷ̏ Object.defineProperty
Slide 23
Slide 23 text
Object.keys(data).forEach(key => { let _value = data[key]; Object.defineProperty(data, key, { get() { console.log('get', key, _value); return _value; }, set(value) { console.log('set', key, _value); _value = value; } }); });
Slide 24
Slide 24 text
Object.keys(data).forEach(key => { let _value = data[key]; const dep = new Dep(); Object.defineProperty(data, key, { get() { dep.depend(); return _value; }, set(value) { _value = value; dep.notify(); } }); }); // ... target = watcher; target(); target = null;
Slide 25
Slide 25 text
console.log(data.total); // => 200 data.quantity = 3; console.log(data.total); // => 300 https://stackblitz.com/edit/vue-reactivity-step-by- step?file=step-99.js
Slide 26
Slide 26 text
https://medium.com/vue-mastery/the-best- explanation-of-javascript-reactivity-fea6112dd80d
Slide 27
Slide 27 text
ৼΓฦΓ • Vue ͷϦΞΫςΟϒγεςϜͷҰ෦Λઆ໌ • Object.defineProperty • Dep class • Watcher
Slide 28
Slide 28 text
ࢀߟࢿྉ • The Best Explanation of JavaScript Reactivity – Vue Mastery – Medium
Slide 29
Slide 29 text
͝੩ௌ͋Γ͕ͱ͏͍͟͝· ͨ͠
Slide 30
Slide 30 text
͓·͚̍ Angular ͷ߹
Slide 31
Slide 31 text
export class AppComponent { price: number; quantity: number; constructor() { this.price = 100; this.quantity = 2; (window as any).app = this; } get total() { return this.price * this.quantity; } } // ίϯιʔϧ͔Β࣮ߦ window.app.quantity = 10; // => DOMߋ৽͞Εͳ͍ // => ϘλϯΫϦοΫͳͲΛ͢Δͱө͞ΕΔ https://stackblitz.com/edit/vue-reactivity-case-of- angular
Slide 32
Slide 32 text
Angular ͷϨϯμϦϯάʹڵຯ͕͋Δํ ຊޠ༁ Angular 2 Change Detection Explained | ͕͓͢͢ΊͰ͢
Slide 33
Slide 33 text
͓·͚̎ Vue Πϯελϯε࡞࣌ͷ࣮ࡍͷ ίʔυΛͬͯΈΔ
Slide 34
Slide 34 text
instance/index • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/index.js#L8 function Vue (options) { • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/index.js#L14 this._init(options)
Slide 35
Slide 35 text
instance/init • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/init.js#L16 Vue.prototype._init = function (options?: Object) { • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/init.js#L57 initState(vm)
Slide 36
Slide 36 text
instance/state • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/state.js#L48 export function initState (vm: Component) { • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/state.js#L54 initData(vm) • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/state.js#L112 function initData (vm: Component) {
Slide 37
Slide 37 text
• https://github.com/vuejs/vue/blob/v2.5.17/src/ core/instance/state.js#L151 observe(data, true /* asRootData */)
Slide 38
Slide 38 text
observer/index • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js export function observe (value: any, asRootData: ?boolean): Observer | void { • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L123 ob = new Observer(value) • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L37 export class Observer {
Slide 39
Slide 39 text
• https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L66 defineReactive(obj, keys[i]) • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L134 export function defineReactive ( • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L156 Object.defineProperty(obj, key, {
Slide 40
Slide 40 text
• https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L162 dep.depend() • https://github.com/vuejs/vue/blob/v2.5.17/src/ core/observer/index.js#L188 dep.notify()