Vue のリアクティブシステム / Reactivity In Vue
by
ryotah
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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()