jeffreyguenther / vue-turbolinks

A Vue mixin to fix Turbolinks caching
MIT License
287 stars 20 forks source link

Issues With Back Button Using Turbolinks With Colcade #29

Closed dalezak closed 4 years ago

dalezak commented 4 years ago

I'm having an issue using Rails + Vue + Turbolinks + Colcade, to position a grid of cards.

I have a simple grid of cards that loads fine initially via vue-colcade, however upon returning to the listing via the back button, the cards are not repositioned.

Our Vue is setup using vue-turbolinks as such

import Vue from 'vue/dist/vue.esm';
import VueColcade from 'vue-colcade';
import TurbolinksAdapter from 'vue-turbolinks';

Vue.use(VueColcade);
Vue.use(TurbolinksAdapter);

document.addEventListener('turbolinks:load', () => {
  const element = document.getElementById('app');
  const app = new Vue({}).$mount(element);
});

The component looks like

<template>
  <div id="cards" class="row cards">
    <div class="col col-sm-12 col-md-6 col-lg-4 d-block"></div>
    <div class="col col-md-6 col-lg-4 d-none d-sm-none d-md-block"></div>
    <div class="col col-lg-4 d-none d-sm-none d-md-none d-lg-block"></div>
    <div class="card shadow-sm mb-4" v-for="item in items" :key="item.id">
      <div class="card-body">
        <h5 class="card-title"><a :href="'/items/' + item.id">{{item.name}}</a></h5>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    items: {
      type: Array,
      required: true
    }
  },
  mounted() {
    this.$colcade.create({
        name: 'cards',  
        el: '#cards',  
        config: {  
          columns: '.col',
          items: '.card',
        },
      });
  }
};
</script>

I posted an issue on vue-colcade but think the problem is related to vue-turbolinks.

excid3 commented 4 years ago

I don't know vue-colcade, but if you could make a small app that showcases the issue so I can fiddle with it, that would be great.

dalezak commented 4 years ago

Hi @excid3, any help would be greatly appreciated! 🙏

Here's the repo https://github.com/dalezak/Rails_Vue_Colcade.

And here's the demo https://rails-vue-colcade.herokuapp.com.

Source Files

Recreate Bug

excid3 commented 4 years ago

This is fantastic. Thanks @dalezak!

excid3 commented 4 years ago

Alrighty, so confirmed this isn't anything to do with vue-turbolinks, and I don't think it's really an issue with vue-colcade either, just your code.

You're creating a colcade instance and never tearing it down or updating it in your code. You need to update or destroy it when the component is destroyed.

vue-colcade caches the instance internally, so it keeps track of the first instance and never creates a second one since you're missing the destroy.

This solves your problem:

export default {
  props: {
    items: {
      type: Array,
      required: true
    }
  },
  mounted() {
    this.$colcade.create({
      name: "cards",
      el: "#cards",
      config: {
        columns: ".col",
        items: ".card"
      }
    });
  },
  destroyed() {
    this.$colcade.destroy("cards")
  }
};

Same rule as always with Turbolinks: Make sure you setup when it mounts and cleanly teardown when you leave the page.

Adding a cleanup before the component is gone fixes it. 👍

dalezak commented 4 years ago

Amazing, thank you @excid3!!