VueJs and Turbolinks

Florent Monbillard edited this page Aug 8, 2017 · 4 revisions

The primary challenge with using Turbolinks with a front-end framework like Vue is managing what happens when Turbolinks caches the page. When Vue mounts a component, it clobbers the element it attaches itself to. As a result, care is needed to ensure the component can be reloaded when a page is rendered from the cache.

To ensure that a Vue can be rebuilt on each turbolinks:load event be they a new request or a request from cache, the component needs to ensure that when it's deleted it restores the element to the pre-mount state.

vue-turbolinks provides a mixin to do just that. It provides beforeMount and destroyed functions for restoring the element to its pre-mount state:

function handleVueDestruction(vue) {
  document.addEventListener('turbolinks:visit', function teardown() {
    vue.$destroy();
    document.removeEventListener('turbolinks:visit', teardown);
  });
}

var TurbolinksAdapter = {
  beforeMount: function() {
    if (this.$el.parentNode) {
      handleVueDestruction(this);
      this.$originalEl = this.$el.outerHTML;
    }
  },
  destroyed: function() {
    this.$el.outerHTML = this.$originalEl;
  }
};

Import and add this mixin to your components and Turbolinks should just work.:tm:

import TurbolinksAdapter from 'vue-turbolinks';

document.addEventListener('turbolinks:load', () => {
  var vueapp = new Vue({
    el: "#hello",
    template: '<App/>',
    mixins: [TurbolinksAdapter],
    components: { App }
  });
});

This adapter is ready for use in Rails using webpacker. See the README for installation instructions.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.