Turbolinks + Vue.js
Pascal Laliberté
Starting small Depth
WHAT I VALUE
Turbolinks Vue.js
WHICH IS WHY I’M ATTRACTED
TO THESE TWO TECHNOLOGIES
Turbolinks
A PAGE HAS A BODY
AND A HEAD
<head>
A PAGE HAS A BODY
<head>
Replaces
the body
with the new
content
<head>
WITH TURBOLINKS, CLICKING A LINK…
<head>
Replaces
the body
with the new
content
<head>
WITH TURBOLINKS, CLICKING A LINK…
Merges
the head
<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
<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
Vue.js
jQuery
In the category of
Front-end UX
Dev Tools
jQuery Vanilla JS
In the category of
Front-end UX
Dev Tools
Angular
A full-fledge client-side
MVC
jQuery Vanilla JS
In the category of
Front-end UX
Dev Tools
React
Angular
A full-fledge client-side
MVC
jQuery Vanilla JS
In the category of
Front-end UX
Dev Tools
React
Angular
A full-fledge client-side
MVC
jQuery Vanilla JS
In the category of
Front-end UX
Dev Tools
View renderers
React
Angular
A full-fledge client-side
MVC
Vue
jQuery Vanilla JS
In the category of
Front-end UX
Dev Tools
View renderers
AS AN EXAMPLE, LET’S TAKE A FORM FIELD
<div class=“purchase-form”>
<input v-model=“quantity”>
AS AN EXAMPLE, LET’S TAKE A FORM FIELD
AS PART OF A PURCHASE FORM…
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
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
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
,
price: 25
}
new Vue({
el: “.purchase-form”,
data: {
quantity: 23
})
23
WE CAN ADD OTHER PROPERTIES TO THE MODEL
,
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
,
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
<map-popover
:lat=“lat”
:long=“long”
:zoom=“zoom”
></map-popover>
DEFINING SUB-COMPONENTS MAKES VUE SCALABLE
React
Angular
Vue
jQuery Vanilla JS
SPA
Front-end UX
vue-router
vue-resource
SPA
YOU CAN GO ALL OUT
AND BUILD A SPA…
Approachable
Small
Fast
Delightful
Scalable
BUT VUE’S BEST QUALITIES ARE THAT IT IS
Now available: Vue.js 2.0
IF YOU WANT
mostly server-generated content
in places: more front-end reactivity
Turbolinks + Vuejs
mostly jQuery / Vanilla js, Unobtrusive JS
<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
new Vue({
el: “.purchase-form”,
data: {
}
quantity: 23
}
23
REACTIVITY = DOM EVENTS, OBSERVERS
DESTROYED WHEN CLONING THE BODY
FOR THE RESTORE CACHE
FOR THE SOLUTION
LET’S LOOK AT THE TIMELINE OF EVENTS
turbolinks:load
FOR THE SOLUTION
LET’S LOOK AT THE TIMELINE OF EVENTS
turbolinks:load turbolinks:before-cache
FOR THE SOLUTION
LET’S LOOK AT THE TIMELINE OF EVENTS
turbolinks:load turbolinks:before-cache
init destroy(Vue.js events)
FOR THE SOLUTION
LET’S LOOK AT THE TIMELINE OF EVENTS
turbolinks:load turbolinks:before-cache
init destroy
re-inject in turbolinks
snapshot the original DOM
element with end data
(serialized) injected
(Vue.js events)
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)
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)
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)
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)
@pascallaliberte
pascallaliberte.me

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