Reputation: 1223
I know how to use masonry.js
apart from vue. However, I'm having issue getting it to function and be called correctly inside of the vue framework. I called it inside of the created or ready but neither seem to get the grid to form correctly. How can i get this to work inside the framework? Oh and I do have jquery called in the html before this script. Here is what I have inside the component :
Edit:
I can see that the masonry is effecting the grid by assigning its height with JS and changing the items to position absolute. However, its not placing them correctly. Its stacking them ontop eachother instead of sideby side like it should be in the grid.
<template>
<div class="projects--container">
<div class="inner-section inner--options">
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</div>
</div>
</template>
<script>
export default{
ready: function () {
this.mason();
},
data: function () {
return {
options: [
{
option: 'projects',
phrase: 'for clients',
slogan: 'slogan...'
},
{
option: 'sides',
phrase: 'for us',
slogan: 'we love what we make'
},
{
option: 'moments',
phrase: 'with the crew'
}
]
}
},
methods: {
revert: function () {
this.$dispatch('return-home', true)
},
mason: function () {
var $grid = $('.grid').masonry({
itemSelector: '.grid-item',
columnWidth: 250
});
$grid.masonry('layout');
}
},
events: {
'option-select': function (option) {
}
}
}
</script>
Upvotes: 18
Views: 6065
Reputation: 9102
I guess the vue-way of doing this is by using refs. Just assign a ref property to your html element inside the template and access it using the vm.$ref instance property inside the mounted callback.
A sample code may look like this:
<template>
<div class="grid" ref="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
</template>
<script>
import Masonry from "masonry"; // or maybe use global scoped variable here
export default {
mounted: function(){
let $masonry = new Masonry(this.$refs.grid, {
// masonry options go in here
// see https://masonry.desandro.com/#initialize-with-vanilla-javascript
});
}
}
</script>
Upvotes: 8
Reputation: 2847
In Vue2, there is no such thing as a ready
lifecycle hook. Instead, the mounted
lifecycle hook is triggered once the instance is "ready" in the way you think of.
Reference: https://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
Upvotes: 7
Reputation: 563
you must call masonry inside mounted()
event to make it work.
i am using this on my project (with imagesloaded) its work perfectly
massonryApply (container, context, selector) {
container = $(`#${container}`)
const $grid = container.imagesLoaded(function () {
$grid.masonry({
itemSelector: `.${selector}`,
percentPosition: true,
columnWidth: `.${selector}`
})
$grid.masonry('reloadItems')
})
}
Upvotes: 0
Reputation: 2076
As I saw it, most mv* frameworks like vue keep DOM elements (view) in sync with js (model), in the other hand, frameworks like masonry just need valid DOM to work. So, the tricky part is to tell one to another when DOM has changed.
So the first change is when vue finished to render all DOM, as mentioned in other answers, we are notified on mounted
lifecycle hook, here is where we can initialize masonry
mounted() {
let grid = document.querySelector('.grid');
this.msnry = new Masonry(grid, {
columnWidth: 25
});
},
In any other change to our view need also update masonry as well, if you change items size use layout()
method, if you add or remove items use reloadItems()
method
methods: {
toggle(item) {
item.isGigante = !item.isGigante;
Vue.nextTick(() => {
// DOM updated
this.msnry.layout();
});
},
add() {
this.items.push({
isGigante: false,
size: '' + widthClasses[Math.floor(Math.random() * widthClasses.length)] + ' ' + heightClasses[Math.floor(Math.random() * heightClasses.length)]
});
Vue.nextTick(() => {
// DOM updated
this.msnry.reloadItems();
this.msnry.layout();
});
}
}
Please note that those methods are called after vue has completed DOM update using Vue.nextTick
function.
Here is a working fiddle.
Upvotes: 9
Reputation: 1
It could be that the vertical stack just indicates that masonry is not working (It's hard to tell without a codepen/plunkr). @riyaz-ali has the right idea though.
Upvotes: 0