Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Pascal Laliberte

September 27, 2016
Tweet

More Decks by Pascal Laliberte

Other Decks in Programming

Transcript

  1. Turbolinks + Vue.js
    Pascal Laliberté

    View Slide

  2. Starting small Depth
    WHAT I VALUE

    View Slide

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

    View Slide

  4. Turbolinks

    View Slide

  5. A PAGE HAS A BODY

    View Slide

  6. AND A HEAD

    A PAGE HAS A BODY

    View Slide


  7. Replaces
    the body
    with the new
    content

    WITH TURBOLINKS, CLICKING A LINK…

    View Slide


  8. Replaces
    the body
    with the new
    content

    WITH TURBOLINKS, CLICKING A LINK…
    Merges
    the head

    View Slide


  9. Replaces
    the body
    with the new
    content

    WITH TURBOLINKS, CLICKING A LINK…
    Merges
    the head
    It keeps a Cache of snapshots

    For Back operations, etc

    View Slide


  10. Replaces
    the body
    with the new
    content

    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

    View Slide

  11. Vue.js

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  18. AS AN EXAMPLE, LET’S TAKE A FORM FIELD

    View Slide



  19. AS AN EXAMPLE, LET’S TAKE A FORM FIELD
    AS PART OF A PURCHASE FORM…

    View Slide

  20. new Vue({
    el: “.purchase-form”,
    data: {
    }
    quantity: null
    })


    WHEN WE SETUP THE VUE INSTANCE, WE SET THE MODEL

    View Slide

  21. new Vue({
    el: “.purchase-form”,
    data: {
    }
    quantity: 2
    }
    2


    })
    AS THE FORM FIELD’S VALUE CHANGES,
    SO DOES THE VALUE IN THE MODEL

    View Slide

  22. new Vue({
    el: “.purchase-form”,
    data: {
    }
    quantity: 23
    }
    23


    })
    AS THE FORM FIELD’S VALUE CHANGES,
    SO DOES THE VALUE IN THE MODEL
    AND VICE VERSA

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  26. :lat=“lat”
    :long=“long”
    :zoom=“zoom”
    >
    DEFINING SUB-COMPONENTS MAKES VUE SCALABLE

    View Slide

  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…

    View Slide

  28. Approachable
    Small
    Fast
    Delightful
    Scalable
    BUT VUE’S BEST QUALITIES ARE THAT IT IS

    View Slide

  29. Now available: Vue.js 2.0

    View Slide

  30. IF YOU WANT
    mostly server-generated content
    in places: more front-end reactivity
    Turbolinks + Vuejs
    mostly jQuery / Vanilla js, Unobtrusive JS

    View Slide


  31. Replaces
    the body
    with the new
    content

    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

    View Slide

  32. new Vue({
    el: “.purchase-form”,
    data: {
    }
    quantity: 23
    }
    23
    REACTIVITY = DOM EVENTS, OBSERVERS
    DESTROYED WHEN CLONING THE BODY
    FOR THE RESTORE CACHE

    View Slide

  33. FOR THE SOLUTION
    LET’S LOOK AT THE TIMELINE OF EVENTS

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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)

    View Slide

  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)

    View Slide

  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)

    View Slide

  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)

    View Slide

  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)

    View Slide

  42. @pascallaliberte
    pascallaliberte.me

    View Slide