Vue 3?
Is this library still being supported? Will it be on Vue.js 3.0?
Yeah, Vue 3 support would be awesome!
vue3 ?
we want vue 3 version. that would be really awesome!!
Ah, so this doesn't work with Vue 3, good to know! xD Vue 3 Support please! @David-Desmaisons
is anyone found the alternative for vue3?
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>
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?