Slide 1

Slide 1 text

Reactivity Learning by accident

Slide 2

Slide 2 text

¯ Accidents “Happy little accidents” Photo by marco forno on Unsplash

Slide 3

Slide 3 text

¯ Photo by Jeremy Bishop on Unsplash Gotcha #1 Adding and removing properties

Slide 4

Slide 4 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { price: 10, quantity: 3, } }, computed: { total () { return this.price * this.quantity }, }, }

{{ total }}

TOTALLY WORKING CODE

Slide 5

Slide 5 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident DEPENDENCY TREE! quantity price total {{total}} 10 3 30 '30'

Slide 6

Slide 6 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident DEPENDENCY TREE! quantity price total {{total}} 3 5 15 '15'

Slide 7

Slide 7 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { quantity: 3, } }, computed: { total () { return this.price * this.quantity }, }, created () { this.price = 10 }, }

{{ total }}

TOTALLY NOT WORKING CODE https://codepen.io/jeffschenck/pen/yKpzPJ

Slide 8

Slide 8 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident DEPENDENCY ISLAND? quantity price total {{total}} 10 3 30 '30'

Slide 9

Slide 9 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident DEPENDENCY ISLAND? quantity price total {{total}} 3 30 '30' 5

Slide 10

Slide 10 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { price: null, quantity: 3, } }, computed: { total () { return this.price * this.quantity }, }, created () { this.price = 10 },

{{ total }}

TOTALLY FIXED WORKING CODE

Slide 11

Slide 11 text

¯ Photo by Annie Spratt on Unsplash Gotcha #2 Modifying array indices

Slide 12

Slide 12 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { todos: ['eat', 'sleep', 'vue'], } }, methods: { addTodo () { this.todos.push('more vue') }, }, } Add
  • {{ todo }}
TOTALLY WORKING CODE

Slide 13

Slide 13 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { todos: ['eat', 'sleep', 'vue'], } }, methods: { updateTodo () { this.todos[0] = 'coffee' }, }, } Update
  • {{ todo }}
TOTALLY NOT WORKING CODE https://codepen.io/jeffschenck/pen/geoGeJ

Slide 14

Slide 14 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident Object.defineProperty(obj, key, { get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) { ... } return value }, set: function reactiveSetter (newVal) { const value = getter ? getter.call(obj) : val if (newVal === value ...) return val = newVal childOb = !shallow && observe(newVal) dep.notify() } }) GETTERS/SETTERS! https://github.com/vuejs/vue/blob/v2.5.16/src/core/observer/index.js#L156

Slide 15

Slide 15 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident BUT WAIT............................ export default { data () { return { todos: ['eat', 'sleep', 'vue'], } }, methods: { addTodo () { this.todos.push('more vue') }, }, }

Slide 16

Slide 16 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident PATCHED ARRAY METHODS! // Totally patched arr.push(...) arr.pop(...) arr.shift(...) arr.unshift(...) arr.splice(...) arr.sort(...) arr.reverse(...) // Totally NOT patched // ...because you totally can't arr[i] = ... arr.length = ... https://github.com/vuejs/vue/blob/v2.5.16/src/core/observer/array.js#L11

Slide 17

Slide 17 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { todos: ['eat', 'sleep', 'vue'], } }, methods: { updateTodo () { this.$set(this.todos, 0, 'coffee') }, }, } Update
  • {{ todo }}
TOTALLY FIXED WORKING CODE

Slide 18

Slide 18 text

¯ Photo by Gabriel Jimenez on Unsplash Gotcha #3 Relying on immediate DOM updates

Slide 19

Slide 19 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { methods: { focusInput () { this.$refs.focus() }, }, } Focus TOTALLY WORKING CODE

Slide 20

Slide 20 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { shown: false, } }, methods: { showInput () { this.shown = true this.$refs.input.focus() }, }, } Show + Focus TOTALLY NOT WORKING CODE https://codepen.io/jeffschenck/pen/aYELPY

Slide 21

Slide 21 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident DOM UPDATES ARE ASYNC! • Buffered • Deduplicated • Efficient

Slide 22

Slide 22 text

Vue Reactivity https://speakerdeck.com/jeffschenck/vue-reactivity-learning-by-accident export default { data () { return { shown: false, } }, methods: { showInput () { this.shown = true this.$nextTick(() => { this.$refs.input.focus() }) }, }, } Update
  • {{ todo }}
TOTALLY FIXED WORKING CODE

Slide 23

Slide 23 text

¯ Photo by Guillaume Jaillet on Unsplash Proxy A bold new future

Slide 24

Slide 24 text

Jeff Schenck Meetup meetup.com/vue-sf Email [email protected] Slides goo.gl/P9L4dZ