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

Vue 3? #79

Open
gitFoxCode opened this issue Jan 11, 2021 · 7 comments
Open

Vue 3? #79

gitFoxCode opened this issue Jan 11, 2021 · 7 comments

Comments

@gitFoxCode
Copy link

Is this library still being supported? Will it be on Vue.js 3.0?

@jakobwinter
Copy link

Yeah, Vue 3 support would be awesome!

@kekekezi
Copy link

kekekezi commented Mar 7, 2022

vue3 ?

@aenzenith
Copy link

we want vue 3 version. that would be really awesome!!

@developerzblock
Copy link

Ah, so this doesn't work with Vue 3, good to know! xD
Vue 3 Support please! @David-Desmaisons

@superdiazzz
Copy link

is anyone found the alternative for vue3?

@roenfeldt
Copy link

A quick solution for when you need minimal filtering capabilities. Using Vue 3 and Tailwind.

<script setup>
// components/QuickIsotope.vue

import {computed, ref} from 'vue';

const catOne = computed(() =>
    'https://fakeimg.pl/480x320/C6011F/eae0d0/?retina=1&font=noto&text=1st Cat'
);
const catTwo = computed(() =>
    'https://fakeimg.pl/480x320/568203/eae0d0/?retina=1&font=noto&text=2nd Cat'
);
const catThree = computed(() =>
    'https://fakeimg.pl/480x320/720e9e/eae0d0/?retina=1&font=noto&text=3rd Cat'
);

const cards = ref([
    {
        id: 1,
        cat: 1,
        title: 'Lorem',
        href: catOne,
    },
    {
        id: 2,
        cat: 2,
        title: 'Ipsum',
        href: catTwo,
    },
    {
        id: 3,
        cat: 3,
        title: 'Dolor',
        href: catThree,
    },
    {
        id: 4,
        cat: 1,
        title: 'Sit',
        href: catOne,
    },
    {
        id: 5,
        cat: 2,
        title: 'Amet',
        href: catTwo,
    },
    {
        id: 6,
        cat: 3,
        title: 'Consectetur',
        href: catThree,
    },
    {
        id: 7,
        cat: 1,
        title: 'Adispicing',
        href: catOne,
    },
    {
        id: 8,
        cat: 2,
        title: 'Elit',
        href: catTwo,
    },
]);

const categories = ref([1, 2, 3]);

const setCategories = (cat = [1]) => {
    categories.value = cat;
};

const categoriesSelected = computed(() => {    
    return cards.value.filter((card) => {
        return categories.value.includes(card.cat);
    });
});
</script>

<template>
<div class="my-16 p-32 w-full bg-yellow-400">
    <button
        class="w-24 bg-orange-700 text-white rounded"
        @click="setCategories([1, 2, 3])"
    >
        All
    </button>
    
    <button
        class="w-24 bg-orange-700 text-white rounded ml-4"
        @click="setCategories([1])"
    >
        Cat 1
    </button>
    
    <button
        class="w-24 bg-orange-700 text-white rounded ml-4"
        @click="setCategories([2])"
    >
        Cat 2
    </button>
    
    <button
        class="w-24 bg-orange-700 text-white rounded ml-4"
        @click="setCategories([3])"
    >
        Cat 3
    </button>
    
</div>

<div class="grid grid-cols-4 place-items-center gap-24 w-full mb-32">
    <transition-group
        enter-active-class="transition duration-150 delay-150 ease-out"
        enter-from-class="opacity-0 scale-0"
        enter-to-class="opacity-100 scale-100"
        leave-active-class="transition duration-150 ease-in"
        leave-from-class="opacity-100 scale-100"
        leave-to-class="opacity-0 scale-0"
    >
        <div
            v-for="card in categoriesSelected"
            :key="card.id"
            :id="'card-' + card.id"
            class="w-48 h-32 bg-orange-700 rounded-2xl overflow-hidden"
        >
                <img
                    :src="card.href"
                    :alt="card.title"
                    class="w-full"
                />
        </div>
    </transition-group>
</div>
</template>

@ktm72
Copy link

ktm72 commented Jun 1, 2023

Hey guys, This is the source code written by chatGpt4 for vue 3. Have a look.

import { merge } from "lodash";
import Isotope from "isotope-layout";
import { onMounted, onBeforeUnmount, onUpdated, ref, watch } from "vue";

function addClass(node, classValue) {
  if (node.data) {
    const initValue = !node.data.staticClass ? "" : node.data.staticClass + " ";
    node.data.staticClass = initValue + classValue;
  }
}

function getItemVm(elmt) {
  return elmt.__underlying_element;
}

export default {
  name: "isotope",

  props: {
    options: {
      type: Object,
      default: () => ({
        layoutMode: "masonry",
        masonry: {
          gutter: 10
        }
      })
    },
    itemSelector: {
      type: String,
      default: "item"
    },
    list: {
      type: Array,
      required: true
    }
  },

  setup(props, { slots, emit }) {
    const prevChildren = ref([]);
    const children = ref([]);
    const removedIndex = ref([]);

    const displayChildren = ref([]);

    const cleanupNodes = () => {
      removedIndex.value.reverse();
      removedIndex.value.forEach(index =>
        children.value.splice(index, 1)
      );
    };

    const link = () => {
      const slotElements = slots.default ? slots.default() : [];
      slotElements.forEach((slot, index) => {
        const elmt = slot.el;
        if (elmt) {
          elmt.__underlying_element = { vm: props.list[index], index };
        }
      });
    };

    const listen = () => {
      const listeners = [];
      Object.values(props.options.getSortData).forEach(sort => {
        props.list.forEach((collectionElement, index) => {
          const unwatch = watch(() => sort(collectionElement), () => {
            iso.value.updateSortData();
            iso.value._requestUpdate();
          });
          listeners.push(unwatch);
        });
      });
      return listeners;
    };

    const iso = ref(null);

    onMounted(() => {
      const options = merge({}, props.options);
      const update = object => {
        Object.entries(object).forEach(([key, value]) => {
          object[key] = itemElement => {
            const res = getItemVm(itemElement);
            return value.call(this, res.vm, res.index);
          };
        });
      };
      update(options.getSortData);
      update(options.getFilterData);
      if (options.filter) {
        options.filter = buildFilterFunction(options.filter);
      }

      link();
      const listeners = listen();
      iso.value = new Isotope(document.querySelector(".isotope"), options);
      iso.value._requestUpdate = () => {
        if (iso.value._willUpdate) return;
        iso.value._willUpdate = true;
        setTimeout(() => {
          iso.value.arrange();
          iso.value._willUpdate = false;
        });
      };
      emit("isotope-instance", iso.value);

      onBeforeUnmount(() => {
        listeners.forEach(unwatch => unwatch());
        iso.value = null;
      });
    });

    onUpdated(() => {
      if (!iso.value) return;

      const newChildren = Array.from(document.querySelector(".isotope").children);
      const added = newChildren.filter(child => !prevChildren.value.includes(child));
      const removed = prevChildren.value.filter(child => !newChildren.includes(child));

      prevChildren.value = newChildren;

      cleanupNodes();
      link();

      if (removed.length === 0 && added.length === 0) return;

      const listeners = listen();

      iso.value.remove(removed);
      iso.value.insert(added);
      iso.value._requestUpdate();

      onBeforeUnmount(() => {
        listeners.forEach(unwatch => unwatch());
        iso.value = null;
      });
    });

    const buildFilterFunction = name => {
      const filter = props.options.getFilterData[name];
      const filterListener = watch(
        () => props.list.map((el, index) => filter(el, index)),
        () => iso.value._requestUpdate()
      );
      onBeforeUnmount(() => {
        filterListener();
      });
      return filter;
    };

    const sort = name => {
      let sortOption = name;
      if (typeof name === "string") {
        sortOption = { sortBy: name };
      }
      arrange(sortOption);
      emit("sort", name);
    };

    const filter = name => {
      const filterOption = buildFilterFunction(name);
      arrange({ filter: filterOption });
      emit("filter", name);
    };

    const unfilter = () => {
      arrange({ filter: () => true });
      emit("filter", null);
    };

    const layout = name => {
      let layoutOption = name;
      if (typeof name === "string") {
        layoutOption = { layoutMode: name };
      }
      arrange(layoutOption);
      emit("layout", layoutOption);
    };

    const arrange = option => {
      iso.value.arrange(option);
      emit("arrange", option);
    };

    const shuffle = () => {
      iso.value.shuffle();
      emit("shuffle");
      emit("sort", null);
    };

    const getFilteredItemElements = () => iso.value.getFilteredItemElements();

    const getElementItems = () => iso.value.getElementItems();

    return {
      iso,
      sort,
      filter,
      unfilter,
      layout,
      arrange,
      shuffle,
      getFilteredItemElements,
      getElementItems
    };
  },

  render() {
    const map = {};
    const prevChildren = this.prevChildren;
    const rawChildren = this.$slots.default || [];
    const children = this.children;
    const removedIndex = this.removedIndex;

    rawChildren.forEach(elt => addClass(elt, this.itemSelector));

    for (let i = 0; i < rawChildren.length; i++) {
      const c = rawChildren[i];
      if (c.type && c.type.name) {
        if (c.key != null && String(c.key).indexOf("__vlist") !== 0) {
          children.push(c);
          map[c.key] = c;
        } else {
          console.log(`Warning template error: isotope children must be keyed: <${c.type.name}>`);
        }
      }
    }

    const displayChildren = [...children];

    if (prevChildren) {
      for (let i = 0; i < prevChildren.length; i++) {
        const c = prevChildren[i];
        if (!map[c.key]) {
          displayChildren.splice(i, 0, c);
          removedIndex.push(i);
        }
      }
    }

    return h("div", { class: "isotope" }, displayChildren);
  }
};

What do you guys think? It should work?

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

8 participants