Making Turbolinks work with Vue.js: Fast server-generated pages with reactive front-end components

Making Turbolinks work with Vue.js: Fast server-generated pages with reactive front-end components

Turbolinks stands against bloated single-page applications with speedy transitions between server-generated pages. Vue.js teaches the big client-side view-renderers how to be small and delightful. Using both together is a little tricky (it's the page restores), and in this talk, we'll go over an approach that works.

A56664d7adfe8cd506c1bc60f9fe2c0a?s=128

Pascal Laliberte

September 27, 2016
Tweet

Transcript

  1. Turbolinks + Vue.js Pascal Laliberté

  2. Starting small Depth WHAT I VALUE

  3. Turbolinks Vue.js WHICH IS WHY I’M ATTRACTED TO THESE TWO

    TECHNOLOGIES
  4. Turbolinks

  5. A PAGE HAS A BODY

  6. AND A HEAD <head> A PAGE HAS A BODY

  7. <head> Replaces the body with the new content <head> WITH

    TURBOLINKS, CLICKING A LINK…
  8. <head> Replaces the body with the new content <head> WITH

    TURBOLINKS, CLICKING A LINK… Merges the head
  9. <head> Replaces the body with the new content <head> WITH

    TURBOLINKS, CLICKING A LINK… Merges the head It keeps a Cache of snapshots
 For Back operations, etc
  10. <head> Replaces the body with the new content <head> WITH

    TURBOLINKS, CLICKING A LINK… Merges the head It keeps a Cache of snapshots
 For Back operations, etc WHICH MAKES PAGE TRANSITIONS
 (AND PAGE RESTORES) SUPER QUICK
  11. Vue.js

  12. jQuery In the category of Front-end UX Dev Tools

  13. jQuery Vanilla JS In the category of Front-end UX Dev

    Tools
  14. Angular A full-fledge client-side MVC jQuery Vanilla JS In the

    category of Front-end UX Dev Tools
  15. React Angular A full-fledge client-side MVC jQuery Vanilla JS In

    the category of Front-end UX Dev Tools
  16. React Angular A full-fledge client-side MVC jQuery Vanilla JS In

    the category of Front-end UX Dev Tools View renderers
  17. React Angular A full-fledge client-side MVC Vue jQuery Vanilla JS

    In the category of Front-end UX Dev Tools View renderers
  18. AS AN EXAMPLE, LET’S TAKE A FORM FIELD

  19. <div class=“purchase-form”> <input v-model=“quantity”> AS AN EXAMPLE, LET’S TAKE A

    FORM FIELD AS PART OF A PURCHASE FORM…
  20. new Vue({ el: “.purchase-form”, data: { } quantity: null })

    <div class=“purchase-form”> <input v-model=“quantity”> WHEN WE SETUP THE VUE INSTANCE, WE SET THE MODEL
  21. new Vue({ el: “.purchase-form”, data: { } quantity: 2 }

    2 <div class=“purchase-form”> <input v-model=“quantity”> }) AS THE FORM FIELD’S VALUE CHANGES, SO DOES THE VALUE IN THE MODEL
  22. new Vue({ el: “.purchase-form”, data: { } quantity: 23 }

    23 <div class=“purchase-form”> <input v-model=“quantity”> }) AS THE FORM FIELD’S VALUE CHANGES, SO DOES THE VALUE IN THE MODEL AND VICE VERSA
  23. , price: 25 } new Vue({ el: “.purchase-form”, data: {

    quantity: 23 }) 23 WE CAN ADD OTHER PROPERTIES TO THE MODEL
  24. , price: 25 } new Vue({ el: “.purchase-form”, data: {

    quantity: 23 }) 23 , computed: { total () { return this.quantity * this.price } } AND COMPUTED PROPERTIES TOO, WHICH UPDATE ON THE FLY
  25. , price: 25 } new Vue({ el: “.purchase-form”, data: {

    quantity: 23 }) 23 methods events components , computed: { total () { return this.quantity * this.price } } YOU CAN ALSO DEFINE
  26. <map-popover :lat=“lat” :long=“long” :zoom=“zoom” ></map-popover> DEFINING SUB-COMPONENTS MAKES VUE SCALABLE

  27. React Angular Vue jQuery Vanilla JS SPA Front-end UX vue-router

    vue-resource SPA YOU CAN GO ALL OUT AND BUILD A SPA…
  28. Approachable Small Fast Delightful Scalable BUT VUE’S BEST QUALITIES ARE

    THAT IT IS
  29. Now available: Vue.js 2.0

  30. IF YOU WANT mostly server-generated content in places: more front-end

    reactivity Turbolinks + Vuejs mostly jQuery / Vanilla js, Unobtrusive JS
  31. <head> Replaces the body with the new content <head> WITH

    TURBOLINKS, CLICKING A LINK… Merges the head It keeps a Cache of snapshots
 For Back operations, etc THE PROBLEM MERGING THEM TOGETHER IS THE BODY REPLACEMENT CAUSES VUE INSTANCES TO LOSE REACTIVITY ON RESTORES Turbolinks + Vuejs
  32. new Vue({ el: “.purchase-form”, data: { } quantity: 23 }

    23 REACTIVITY = DOM EVENTS, OBSERVERS DESTROYED WHEN CLONING THE BODY FOR THE RESTORE CACHE
  33. FOR THE SOLUTION LET’S LOOK AT THE TIMELINE OF EVENTS

  34. turbolinks:load FOR THE SOLUTION LET’S LOOK AT THE TIMELINE OF

    EVENTS
  35. turbolinks:load turbolinks:before-cache FOR THE SOLUTION LET’S LOOK AT THE TIMELINE

    OF EVENTS
  36. turbolinks:load turbolinks:before-cache init destroy (Vue.js events) FOR THE SOLUTION LET’S

    LOOK AT THE TIMELINE OF EVENTS
  37. turbolinks:load turbolinks:before-cache init destroy re-inject in turbolinks snapshot the original

    DOM element with end data (serialized) injected (Vue.js events)
  38. turbolinks:load turbolinks:before-cache init destroy save initial DOM element before it’s

    walked re-inject in turbolinks snapshot the original DOM element with end data (serialized) injected (Vue.js events)
  39. turbolinks:load turbolinks:before-cache init destroy save initial DOM element before it’s

    walked re-inject in turbolinks snapshot the original DOM element with end data (serialized) injected detect serialized start data attached to initial DOM element (Vue.js events)
  40. turbolinks:load turbolinks:before-cache init destroy save initial DOM element before it’s

    walked re-inject in turbolinks snapshot the original DOM element with end data (serialized) injected detect serialized start data attached to initial DOM element Vue.js Mixin (Vue.js events)
  41. turbolinks:load turbolinks:before-cache init destroy save initial DOM element before it’s

    walked re-inject in turbolinks snapshot the original DOM element with end data (serialized) injected detect serialized start data attached to initial DOM element Vue.js Mixin …for each Vue component on the page (Vue.js events)
  42. @pascallaliberte pascallaliberte.me