Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuxt.js usage example #48

Open
AndrewBogdanovTSS opened this issue Mar 6, 2018 · 14 comments
Open

Nuxt.js usage example #48

AndrewBogdanovTSS opened this issue Mar 6, 2018 · 14 comments

Comments

@AndrewBogdanovTSS
Copy link

Please, add Nuxt.js setup example in the documentation getting started section

@vinkodlak
Copy link

plugins/vue-isotope.js

import Vue from 'vue'
import isotope from 'vueisotope'

Vue.component('isotope', isotope)

if using vue-imagesLoaded for images
plugins/vue-imagesLoaded.js

import Vue from 'vue'
import imagesLoaded from 'vue-images-loaded'

Vue.directive('images-loaded', imagesLoaded)

nuxt.config.js

  plugins: [
      { src: '~/plugins/vue-isotope', ssr: false },
      { src: '~/plugins/vue-imagesLoaded', ssr: false },
  ],

index.vue

<no-ssr>
  <isotope ...
</no-ssr>

@AndrewBogdanovTSS
Copy link
Author

why should we specify ssr:false?

@Nisthar
Copy link

Nisthar commented Apr 25, 2018

@AndrewBogdanovTSS Its to turn off Server side rendering. Looks like this package doesn't support SSR.
Most of the alternatives doesn't support this feature either.

@Meuss
Copy link

Meuss commented Dec 7, 2018

@vinkodlak Thanks for the example. I got it to work with Nuxt thanks to your example, but now I'm stuck again when trying to add a filter method...

index.vue

<no-ssr>
  <isotope :options="options" :list="list">
    <div v-for="(item, index) in items" :key="index" class="list-item">
      <h2>{{item.title}}</h2>
    </div>
  </isotope>
  <button @click="filter('something')">filter</button>
</no-ssr>

...
data() {
  return {
    list: [...],
    options: {
      itemSelector: '.list-item',
      layout: 'fitRows',
    },
  };
},
methods: {
  filter(key) => {
    this.filter(key);
  },
}

I've tried multiple different methods to try to get this working, I can't seem to figure out how to filter/arrange/sort the isotope once it is created. Could somebody give a simple example for Nuxt?

@Meuss
Copy link

Meuss commented Dec 13, 2018

I wasn't able to make filtering work with Nuxt :-/ I ended up using the regular isotope-layout npm package instead, and got it working right away. But still very interested if anyone has an example with vueisotope.

@syed-haroon
Copy link

syed-haroon commented Dec 13, 2018

@Meuss follow all steps that @vinkodlak did and do what I have done in one of my projects like here:

.projects {
  .thumbnail {
    width: 243px;
    height: 149px;

    .thumbnail-overlay {
      opacity: 0;
      background-color: rgba(black, 0.8);
      transition: opacity 0.25s ease-in-out;
    }

    &:hover {
      .thumbnail-overlay {
        opacity: 1;
      }
    }
  }
}
<template lang="pug">
  .container
    .row
      .col-md-4.py-5
        ul.list-unstyled.mb-0
          li(v-for="(val, key) in option.getFilterData" ).mb-3
            div(
              :class="[key === filterOption ? 'text-success' : 'text-white']"
              @click="filter(key)",
            ).cursore-pointer {{ key }}

      .col-md-8.d-flex
        .m-auto.w-100
          no-ssr
            isotope(
              ref='projects'
              :options="option",
              :list="projects"
            )
              div(v-for="(item, index) in projects", :key="index").text-white.thumbnail
                div.cursore-pointer.d-block.pos-r.p-1
                  img(:src="require(`../assets/images/project-thumbnails/${item.thumbnail}`)").w-100
                  .pin.pin-xy.d-flex.text-white.thumbnail-overlay
                    .m-auto.fs-16.text-center {{ item.title }}
</template>

<script>
export default {
  name: 'SectionProjects',
  data() {
    return {
      filterOption: 'Show All',

      option: {
        getFilterData: {
          'Show All'() {
            return true;
          },
          'Production Housing'(itemElem) {
            return itemElem.categories.map(x => x === 'Production Housing').includes(true);
          },
          'Remodel Design'(itemElem) {
            return itemElem.categories.map(x => x === 'Remodel Design').includes(true);
          },
          'Commercial Buildings'(itemElem) {
            return itemElem.categories.map(x => x === 'Commercial Buildings').includes(true);
          },
          'Land Planning'(itemElem) {
            return itemElem.categories.map(x => x === 'Land Planning').includes(true);
          },
        },
      },

      projects: [
        {
          title: 'Natomas Meadows Clubhouse',
          thumbnail: 'natomas-meadows-clubhouse.png',
          categories: ['Commercial Buildings', 'Land Planning'],
        }, {
          title: 'Donner Lake Remodel',
          thumbnail: 'donner-lake-remodel.png',
          categories: ['Remodel Design'],
        }, {
          title: 'Havenwood',
          thumbnail: 'havenwood.png',
          categories: ['Production Housing'],
        },
      ],
    };
  },

  methods: {
    filter(key) {
      if (this.filterOption !== key) {
        this.$refs.projects.filter(key);
        this.filterOption = key;
      }
    },
  },
};
</script>

@Meuss
Copy link

Meuss commented Dec 17, 2018

Hey @miaaw , I actually did not register the isotope-layout plugin correctly either. I ended up directly using the package in the page I was using. This is probably bad practice (I'm new to Nuxt), but I got it working easily, something like this:

page.vue:

<template>
  <div class="page">
    <div class="filters">
        <a @click="filterItems('selectorA')">filter A</a>
        <a @click="filterItems('selectorB')">filter B</a>
        <a @click="filterItems('selectorC')">filter C</a>
    </div>
    <div class="items">
      <no-ssr>
        <nuxt-link
          v-for="(item, index) in items"
          :key="index"
          :to="item.url"
          class="item"
        >
        </nuxt-link>
      </no-ssr>
    </div>
  </div>
</template>

<script>
let Isotope;
if (process.browser) {
  Isotope = require('isotope-layout');
}
export default {
  data() {
    return {
      items: [],
      iso: null,
    };
  },
  created() {
    const that = this;
    this.$axios
      .get('/items')
      .then(response => {
        const items = response.data;
        items.forEach(item => {
          that.items.push(item);
        });
      })
      .then(() => {
        that.isotope();
      })
      .catch(error => {
        console.warn('❌:', error.message);
      });
  },
  methods: {
    isotope() {
      this.iso = new Isotope('.items', {
        itemSelector: '.item',
        layout: 'fitRows',
      });
      this.iso.layout();
    },
    filterItems(selector) {
      this.iso.arrange({ filter: `${selector}` });
    },
  },
};
</script>

I hope this helps!

@Meuss
Copy link

Meuss commented Dec 17, 2018

@syed-haroon Thanks for your example. I'm gonna try to get vueisotope running again.

@gothaicenter
Copy link

@Meuss follow all steps that @vinkodlak did and do what I have done in one of my projects like here:

.projects {
  .thumbnail {
    width: 243px;
    height: 149px;

    .thumbnail-overlay {
      opacity: 0;
      background-color: rgba(black, 0.8);
      transition: opacity 0.25s ease-in-out;
    }

    &:hover {
      .thumbnail-overlay {
        opacity: 1;
      }
    }
  }
}
<template lang="pug">
  .container
    .row
      .col-md-4.py-5
        ul.list-unstyled.mb-0
          li(v-for="(val, key) in option.getFilterData" ).mb-3
            div(
              :class="[key === filterOption ? 'text-success' : 'text-white']"
              @click="filter(key)",
            ).cursore-pointer {{ key }}

      .col-md-8.d-flex
        .m-auto.w-100
          no-ssr
            isotope(
              ref='projects'
              :options="option",
              :list="projects"
            )
              div(v-for="(item, index) in projects", :key="index").text-white.thumbnail
                div.cursore-pointer.d-block.pos-r.p-1
                  img(:src="require(`../assets/images/project-thumbnails/${item.thumbnail}`)").w-100
                  .pin.pin-xy.d-flex.text-white.thumbnail-overlay
                    .m-auto.fs-16.text-center {{ item.title }}
</template>

<script>
export default {
  name: 'SectionProjects',
  data() {
    return {
      filterOption: 'Show All',

      option: {
        getFilterData: {
          'Show All'() {
            return true;
          },
          'Production Housing'(itemElem) {
            return itemElem.categories.map(x => x === 'Production Housing').includes(true);
          },
          'Remodel Design'(itemElem) {
            return itemElem.categories.map(x => x === 'Remodel Design').includes(true);
          },
          'Commercial Buildings'(itemElem) {
            return itemElem.categories.map(x => x === 'Commercial Buildings').includes(true);
          },
          'Land Planning'(itemElem) {
            return itemElem.categories.map(x => x === 'Land Planning').includes(true);
          },
        },
      },

      projects: [
        {
          title: 'Natomas Meadows Clubhouse',
          thumbnail: 'natomas-meadows-clubhouse.png',
          categories: ['Commercial Buildings', 'Land Planning'],
        }, {
          title: 'Donner Lake Remodel',
          thumbnail: 'donner-lake-remodel.png',
          categories: ['Remodel Design'],
        }, {
          title: 'Havenwood',
          thumbnail: 'havenwood.png',
          categories: ['Production Housing'],
        },
      ],
    };
  },

  methods: {
    filter(key) {
      if (this.filterOption !== key) {
        this.$refs.projects.filter(key);
        this.filterOption = key;
      }
    },
  },
};
</script>

Please help! how to define dynamic function for categories in getFilterData:{ ... } ?

@PuxianAlHazred
Copy link

Doesn't work for me

@zakarialounes
Copy link

zakarialounes commented May 14, 2019

Thanks @vinkodlak #48 (comment) and @Meuss #48 (comment), your methods works!
The @Meuss method has the advantage to be compatible in SSR mode 👍 to be functional, rename the method "created()" by "computed()". An example for who don't succeed: https://codesandbox.io/embed/1o8j26k5l7 :)

@Feldbot
Copy link

Feldbot commented Sep 9, 2019

Hi, I am also trying to use with Nuxt. I'm trying the basic SPA, not SSR as mentioned elsewhere in this thread. I tried modifying the basic example from the docs, so that it would work with import/export statements. Some of the isotope functionality is working, but I am having issues with the v-model inputs and how the DOM reactivity is updating. If I click on a person cell and enter a new id number in the input field, instead of filtering and resorting by that new id, it is somehow creating a new cell for every keystroke. So for example if a person has an id of 5, if I click on that and enter "55", then it keeps 5 and adds another cell with 55. Likewise, if I have 55 in the field and delete the input value, the previously populated people/id cells remain. I am new to Vue so I'm not sure if I have set up the components correctly, or if there is a bug. I have my modified example here.

Also, I'm not sure if this has to do with the problem, but I was confused by the docs Installation section saying there was a recommendation for webpack, not sure if I need to incorporate this into the code. I assumed vueisotope would already be configured to use webpack.

@salehmkhlsi
Copy link

yo guys i think it dosent work with nuxt 3 but i am trying to use it with nuxt 3 although its not working could you guys help me

@salehmkhlsi
Copy link

<template>
  <div class="p-4 flex flex-col space-y-4">
    <div class="button-group-wrap">
      <h3 class="text-2xl pb-2">Filter</h3>
      <div
        id="filters"
        class="button-group flex space-x-2 class filter-button-group"
      >
        <button
          @click="gettingvalue"
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-filter="*"
        >
          show all
        </button>
        <button
          @click="gettingvalue"
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-filter=".cms"
        >
          cms
        </button>
        <button
          @click="gettingvalue"
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-filter=".markup"
        >
          markup
        </button>
        <button
          @click="gettingvalue"
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-filter=".programming"
        >
          programming
        </button>
      </div>
      <br />
      <h3 class="text-2xl pb-2">Sort</h3>
      <div id="sorts" class="button-group flex space-x-2 sort-by-button-group">
        <button
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-sort-by="original-order"
        >
          original order
        </button>
        <button
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-sort-by="number"
        >
          id
        </button>
        <button
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-sort-by="name"
        >
          name
        </button>
        <button
          class="bg-slate-700 text-white p-2 rounded-xl"
          data-sort-by="category"
        >
          category
        </button>
      </div>
    </div>

    <div class="box-listin flex flex-wrap gap-2">
      <div
        class="box-item bg-slate-300 programming"
        data-category="programming"
      >
        <h3 class="item-name">JavaScript</h3>
        <h3 class="item-id">12</h3>
        <div class="item-category bg-slate-400">Programming</div>
      </div>
      <div class="box-item bg-slate-300 markup" data-category="markup">
        <h3 class="item-name">HTML</h3>
        <h3 class="item-id">9</h3>
        <div class="item-category">Markup</div>
      </div>
      <div class="box-item bg-slate-300 cms" data-category="cms">
        <h3 class="item-name">HubSpot</h3>
        <h3 class="item-id">4</h3>
        <div class="item-category">CMS</div>
      </div>
      <div
        class="box-item bg-slate-300 programming"
        data-category="programming"
      >
        <h3 class="item-name">Java</h3>
        <h3 class="item-id">25</h3>
        <div class="item-category">Programming</div>
      </div>
      <div class="box-item bg-slate-300 cms" data-category="cms">
        <h3 class="item-name">WordPress</h3>
        <h3 class="item-id">10</h3>
        <div class="item-category">CMS</div>
      </div>
      <div class="box-item bg-slate-300 markup" data-category="markup">
        <h3 class="item-name">XML</h3>
        <h3 class="item-id">58</h3>
        <div class="item-category">Markup</div>
      </div>
      <div class="box-item bg-slate-300 cms" data-category="cms">
        <h3 class="item-name">Drupal</h3>
        <h3 class="item-id">2</h3>
        <div class="item-category">CMS</div>
      </div>
      <div
        class="box-item bg-slate-300 programming"
        data-category="programming"
      >
        <h3 class="item-name">C++</h3>
        <h3 class="item-id">42</h3>
        <div class="item-category">Programming</div>
      </div>
      <div class="box-item bg-slate-300 markup" data-category="markup">
        <h3 class="item-name">HubL</h3>
        <h3 class="item-id">{{ test }}</h3>
        <div class="item-category">Markup</div>
      </div>
    </div>
  </div>
</template>

<!-- <script setup>
const list = [
  {
    name: "John",
    id: 25,
  },
  {
    name: "Joao",
    id: 7,
  },
  {
    name: "Albert",
    id: 12,
  },
  {
    name: "Jean",
    id: 100,
  },
];
</script> -->
<!-- <script>
export default {
  crerated() {
    this.relayout();
    console.log("test");
  },
  data() {
    return {
      isotope: null,
      test: 212,
    };
  },
  methods: {
    relayout() {
      let elem = document.querySelector(".box-listin");
      this.isotope = new Isotope(elem, {
        itemSelector: ".box-item",
        layoutMode: "masonry",
        getSortData: {
          number: "item-is parseint",
          name: "item-name",
          category: "[data-category]",
        },
      });
    },
  },
};
</script>  -->
<!-- <script>
export default {
  crerated() {
    this.relayout();
    console.log("test");
  },
  data() {
    return {
      options: {
        itemSelector: ".list-item",
        layout: "fitRows",
      },
    };
  },
  methods: {
    filter(key) {
      this.filter(key);
    },
  },
};
</script> -->

<!-- <script setup>
// const isotope = ref(null);

// onMounted(() => {
//   const elem = document.querySelector(".box-listin");
//   isotope.value = new isotope(elem, {
//     itemSelector: ".box-item",
//     layoutMode: "masonry",
//   });
// });
// </script> -->
<style scoped></style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants