Using Masonry.JS and Vue.JS
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>
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://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
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.