<div id="app"></div>
* {
    box-sizing: border-box;
  }
  .masonry-wrap {
    max-width: 1000px;
    padding: 50px;
  }
  .masonry-item {
    width: 160px;
    height: 100px;
    margin-bottom: 20px;
    .card {
      padding: 1rem;
      height: 100%;
      background: rgb(225, 225, 225);
      border-radius: 5px;
      border: 1px solid rgb(200, 200, 200);
    }
  }
  .masonry-item-1, .masonry-item-7, .masonry-item-12 {
    height: 200px;
  }
  .masonry-item-3, .masonry-item-9 {
    height: 150px;
  }
View Compiled
const mixin = {
  methods: {
    masonry(element, optoins) {
      return new Masonry(element, optoins);
    }
  }
};

const App = {
  template: `
    <div class="masonry-wrap" ref="masonry">
      <div class="masonry-item" v-for="item in 12" :key="item" :class="item">
        <div class="card">
          {{ item }}
        </div>
      </div>
    </div>
  `,
  mixins: [ mixin ],
  mounted() {
    this.masonry(this.$refs.masonry, {
      columnWidth: 160,
      gutter: 20,
      itemSelector: '.masonry-item',
      transitionDuration: '0.3s',
      horizontalOrder: true
    });
  }
};

new Vue({
  render: (h) => h(App)
}).$mount('#app');

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.8/vue.min.js
  2. https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js