Slide 1

Slide 1 text

Vue.jsのReactiveの中を のぞいてみた件 morifuji kodai @marooon88

Slide 2

Slide 2 text

流れ ● 誰? ● こんな経験ないですか ● やってみた ● まとめ

Slide 3

Slide 3 text

● 名前 ○ morifuji ○ @marooon88 ● 趣味 ○ kotlin ○ ゲーム(switch) ● 会社 ○ atma株式会社 ○ サーバーサイドエンジニア ■ 最近はvue.js成分多め 誰?

Slide 4

Slide 4 text

サーバーサイドエンジニア・フロントエンドエンジニア 絶賛採用中 誰?

Slide 5

Slide 5 text

サーバーサイドエンジニア・フロントエンドエンジニア 絶賛採用中 誰?

Slide 6

Slide 6 text

こんな経験ないですか objectにプロパティを加え ても反映されない this.$refs経由の dom操作ができない 僕たちはリアクティブ に振り回されている

Slide 7

Slide 7 text

こんな経験ないですか https://jp.vuejs.org/v2/guide/reactivity.html

Slide 8

Slide 8 text

こんな経験ないですか https://jp.vuejs.org/v2/guide/reactivity.html ほんとに?

Slide 9

Slide 9 text

observer/index.js index.js /vue/dev/src/core/*

Slide 10

Slide 10 text

observer/index.js index.js /vue/dev/src/core/* 無理

Slide 11

Slide 11 text

やってみた 実際にアプリケーションを動かして どう変化するかを観測 Evan you 氏のサンプルアプリを拝借。 感謝 連携

Slide 12

Slide 12 text

addTodo: function () { var value = this.newTodo && this.newTodo.trim() if (!value) { return } this.todos.push({ id: todoStorage.uid++, title: value, completed: false }) this.newTodo = '' }, やってみた

Slide 13

Slide 13 text

addTodo: function () { var value = this.newTodo && this.newTodo.trim() if (!value) { return } this.todos.push({ id: todoStorage.uid++, title: value, completed: false }) this.newTodo = '' }, やってみた Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() if (Array.isArray(value)) { dependArray(value) } } } return value },

Slide 14

Slide 14 text

addTodo: function () { var value = this.newTodo && this.newTodo.trim() if (!value) { return } this.todos.push({ id: todoStorage.uid++, title: value, completed: false }) this.newTodo = '' }, やってみた Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() if (Array.isArray(value)) { dependArray(value) } } } return value }, depend () { if (Dep.target) { Dep.target.addDep(this) } }

Slide 15

Slide 15 text

やってみた https://jp.vuejs.org/v2/guide/reactivity.html

Slide 16

Slide 16 text

やってみた doneEdit: function (todo) { if (!this.editedTodo) { return } this.editedTodo = null todo.title = todo.title.trim() if (!todo.title) { this.removeTodo(todo) } },

Slide 17

Slide 17 text

やってみた doneEdit: function (todo) { if (!this.editedTodo) { return } this.editedTodo = null todo.title = todo.title.trim() if (!todo.title) { this.removeTodo(todo) } }, Object.defineProperty (obj, key, { enumerable: true, configurable: true, get: …………, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if (process.env.NODE_ENV !== 'production' && customSetter ) { customSetter () } // #7981: for accessor properties without setter if (getter && !setter) return if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = !shallow && observe(newVal) dep.notify() }

Slide 18

Slide 18 text

やってみた doneEdit: function (todo) { if (!this.editedTodo) { return } this.editedTodo = null todo.title = todo.title.trim() if (!todo.title) { this.removeTodo(todo) } }, Object.defineProperty (obj, key, { enumerable: true, configurable: true, get: …………, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if (process.env.NODE_ENV !== 'production' && customSetter ) { customSetter () } // #7981: for accessor properties without setter if (getter && !setter) return if (setter) { setter.call(obj, newVal) } else { val = newVal } childOb = !shallow && observe(newVal) dep.notify() } notify () { // stabilize the subscriber list first const subs = this.subs.slice() if (process.env.NODE_ENV !== 'production' && !config.async) { // subs aren't sorted in scheduler if not running async // we need to sort them now to make sure they fire in correct // order subs.sort((a, b) => a.id - b.id) } for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } }

Slide 19

Slide 19 text

やってみた https://jp.vuejs.org/v2/guide/reactivity.html

Slide 20

Slide 20 text

なんやこれクソ仕様やんけ!! 仕方ないよなぁ(畏怖) 寛大な心 まとめ こういう処理どうするんやろう こう書けばええんか! 新たな知見

Slide 21

Slide 21 text

ご静聴ありがとうございました 参考資料 ● リアクティブの探求 ○ https://jp.vuejs.org/v2/guide/reactivity.html ● Understanding Rendering Process with Virtual DOM In Vue.js ○ https://medium.com/@koheimikami/understanding-rendering-process-with-virtual-dom-in-vue-js-a6e602811782 ● Evan you 氏のサンプルアプリ ○ https://github.com/vuejs/vue/tree/dev/examples/todomvc ● madge(依存関係を可視化するnpmライブラリ) ○ https://github.com/pahen/madge まとめ