A pure vue responsive masonry layout without direct dom manipulation
vue-masonry-wall
A pure vue responsive masonry implementation without direct dom manipulation, ssr friendly with lazy appending. I created this because other libraries has no SSR support, and I needed a pure vue implementation.
Installation
npm i vue-masonry-wall
# or yarn
yarn add vue-masonry-wall
Features
- No Direct DOM Manipulation
 - SSR friendly, able to load and re hydrate later
 - 1 dependency only, no legacy dependencies
 - Auto lazy appending, scroll to auto load more
 - Auto item placement, will find best column
 - Responsive design
 
Usage
<vue-masonry-wall :items="items" :options="options" @append="append"/>
const items = []
const options = {
  width: 300,
  padding: {
    default: 12,
    1: 6,
    2: 8
  }
}
const append = () => {
  // API call and add items
  this.items.push(...[])
}
Basic
<template>
  <div id="app">
    <h2>Masonry: append endlessly</h2>
    <vue-masonry-wall :items="items" :options="{width: 300, padding: 12}" @append="append">
      <template v-slot:default="{item}">
        <div class="item">
          <h5>{{item.title}}</h5>
          <p>{{item.content}}</p>
        </div>
      </template>
    </vue-masonry-wall>
  </div>
</template>
<script>
  import VueMasonryWall from "vue-masonry-wall";
  export default {
    name: 'app',
    components: {VueMasonryWall},
    data() {
      return {
        items: [
          {title: 'Item 0', content: 'Content'},
          {title: 'Item 1', content: 'Content'},
        ]
      }
    },
    methods: {
      /**
       * I am mocking a API call that load 20 objects at a time.
       */
      append() {
        for (let i = 0; i < 20; i++) {
          this.items.push({title: `Item ${this.items.length}`, content: 'Content'})
        }
      }
    }
  }
</script>
Nuxt SSR
Add :ssr="{columns: 2}" to masonry so that during SSR, it will be load in 2 columns.
SSR has no clue what is the size of your height of your element or width of the browser.
You can however guess based on user-agent: https://github.com/nuxt-community/device-module
This param allow you to preload a config for SSR rendering, it will distribute your items into all columns evenly.
<vue-masonry-wall :items="items" :options="{width: 300, padding: 12}" :ssr="{columns: 2}" @append="append">
  <template v-slot:default="{item}">
    <div class="item">
      <h5>{{item.title}}</h5>
      <p>{{item.content}}</p>
    </div>
  </template>
</vue-masonry-wall>