[Vuejs]-Masonry.js not applaying layout

0👍

Main point: You gotta trigger Masonry again after adding new image.

Masonry works by setting fixed position, width, etc… to the elements. So everytime something is added/removed, you should trigger Masonry to recalculate and set again the fixed position, width, etc…

e.g. https://codesandbox.io/s/4xw830q1r4 components/Hello.vue

<template>
    <div class="hello">
        <button @click="addImg"> add img </button>
        <br/><br/>
        <div class="grid">
            <div class="grid-item"  v-for="img in imgs">
                <img :src="img">
            </div>
        </div>
    </div>
</template>

<script>
    import Masonry from 'masonry-layout';

    export default {
  name: 'hello',
  data () {
    return {
            imgs:[
                `https://unsplash.it/200/300/?random=${Math.random()}`,
                `https://unsplash.it/200/100/?random=${Math.random()}`,
                `https://unsplash.it/200/400/?random=${Math.random()}`,
                `https://unsplash.it/200/250/?random=${Math.random()}`
            ]
    }
  },
    mounted() {
        this.triggerMasonry();
    },
    methods:{
        triggerMasonry() {
            console.log('triggerMasonry');
            var grid = document.querySelector('.grid');
            var msnry = new Masonry( grid, {
                itemSelector: '.grid-item',
                columnWidth: 200
            });
        },
        addImg(){
            this.imgs.push(`https://unsplash.it/200/300/?random=${Math.random()}`);
            this.$nextTick(()=>{
                this.triggerMasonry();
            });
        }
    }
}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.grid {
    width: 100%;
    img {
        width: 100%;
    }
}
</style>

triggerMasonry on mounted, and also triggerMasonry after a new image is added.

You will also need to use nextTick to triggerMasonry only after the image has been added to DOM.

Leave a comment