Martyn
Martyn

Reputation: 6383

Using IsotopeJS on list items within a Vue 3 template

I'm trying to use isotopeJS filtering but the list container is inside my Vue3 template. I've tried to use v-pre to tell the renderer to ignore the list as it doesn't need any Vue3 rendering. Also, I've tried using the onUpdated hook to hopefully do the filtering after re-rendering but the filtering only works when I remove the list container out of the Vue template.

<div id="app">
  <!-- checkbox filters that are rendered using Vue 3. These filters are used to filter isotope list -->

  <div class="row row-cols-3" id="list-container" v-pre>
    <!-- list items.. i don't want vue to touch these but ideally want it to sit between checkboxes and pagination -->
  </div>

  <!-- pagination html that is rendered using Vue 3 -->
</div>

Here is my setup() function:

const app = createApp({
  setup() {

    // ...

    // init isotope
    const $grid = $('#list-container')

    onMounted(() => {
      console.log("onMounted");
      $grid.isotope({
        itemSelector: '[data-list-item]',
        layoutMode: 'fitRows',
      })
    })

    onUpdated(() => {
      console.log("onUpdated");
      setTimeout(() => $grid.isotope({
        filter: function () {
          // filtering logic
        }
      }), 200);
    })

    return {
      // ...
    }
  }
})

The onMounted and onUpdated is output to the console when I expect them to but nothing happens with the isotope filtering.

However, if I move the isotope list container out of the app template, it works:

<div id="app">
  <!-- checkbox filters that are rendered using Vue 3. These filters are used to filter isotope list -->

  <!-- pagination html that is rendered using Vue 3 -->
</div>

<div class="row row-cols-3" id="list-container">
  <!-- list items.. -->
</div>

But this isn't ideal, as I want the list to sit between the checkboxes and pagination.

The only solution I've found in the past is 2 different Vue apps:

<div id="app1">
  <!-- checkbox filters that are rendered using Vue 3. These filters are used to filter isotope list -->
</div>

<div class="row row-cols-3" id="list-container">
  <!-- list items.. i don't want vue to touch these but ideally want it to sit between checkboxes and pagination -->
</div>

<div id="app2">
  <!-- pagination html that is rendered using Vue 3 -->
</div>

.. but it makes it more complex as I have to share properties between apps. Would be must simpler to have it all under one app. I'm wondering if it's something to do with Vue detecting a change to the DOM, and "correcting" it all very quickly that it looks like nothing is happening.. but this is just a theory. I tried to use onUpdated to hopefully fire after any such rendering.

Upvotes: 0

Views: 131

Answers (0)

Related Questions