title: VueJS masonry layout
body: <p>Currently, I'm working on the VueJS project and Its vue cli 3. I'm trying to implement MasonryJS to my Vue project, but I'm stuck.  I could not understand how can I implement this kind of masonry layout for my vue project.  </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>;
  (function(window) {
  
    /**
     * GridLoaderFx obj.
     */
    function GridLoaderFx(el, options) {
      this.el = el;
      this.items = this.el.querySelectorAll('.grid__item &gt; .grid__link');
    }
  
    /**
     * Effects.
     */
    GridLoaderFx.prototype.effects = {
  
      'Shu': {
        lineDrawing: true,
        animeLineDrawingOpts: {
          duration: 800,
          delay: function(t, i) {
            return i * 150;
          },
          easing: 'easeInOutSine',
          strokeDashoffset: [anime.setDashoffset, 0],
          opacity: [{
              value: [0, 1]
            },
            {
              value: [1, 0],
              duration: 200,
              easing: 'linear',
              delay: 500
            }
          ]
        },
        animeOpts: {
          duration: 800,
          easing: [0.2, 1, 0.3, 1],
          delay: function(t, i) {
            return i * 150 + 800;
          },
          opacity: {
            value: [0, 1],
            easing: 'linear'
          },
          scale: [0.5, 1]
        }
      }
    };
  
    GridLoaderFx.prototype._render = function(effect) {
      // Reset styles.
      this._resetStyles();
  
      var self = this,
        effectSettings = this.effects[effect],
        animeOpts = effectSettings.animeOpts
  
      if (effectSettings.perspective != undefined) {
        [].slice.call(this.items).forEach(function(item) {
          item.parentNode.style.WebkitPerspective = item.parentNode.style.perspective = effectSettings.perspective + 'px';
        });
      }
  
      if (effectSettings.origin != undefined) {
        [].slice.call(this.items).forEach(function(item) {
          item.style.WebkitTransformOrigin = item.style.transformOrigin = effectSettings.origin;
        });
      }
  
      if (effectSettings.lineDrawing != undefined) {
        [].slice.call(this.items).forEach(function(item) {
          // Create SVG.
          var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
            path = document.createElementNS('http://www.w3.org/2000/svg', 'path'),
            itemW = item.offsetWidth,
            itemH = item.offsetHeight;
  
          svg.setAttribute('width', itemW + 'px');
          svg.setAttribute('height', itemH + 'px');
          svg.setAttribute('viewBox', '0 0 ' + itemW + ' ' + itemH);
          svg.setAttribute('class', 'grid__deco');
          path.setAttribute('d', 'M0,0 l' + itemW + ',0 0,' + itemH + ' -' + itemW + ',0 0,-' + itemH);
          path.setAttribute('stroke-dashoffset', anime.setDashoffset(path));
          svg.appendChild(path);
          item.parentNode.appendChild(svg);
        });
  
        var animeLineDrawingOpts = effectSettings.animeLineDrawingOpts;
        animeLineDrawingOpts.targets = this.el.querySelectorAll('.grid__deco &gt; path');
        anime.remove(animeLineDrawingOpts.targets);
        anime(animeLineDrawingOpts);
      }
  
      if (effectSettings.revealer != undefined) {
        [].slice.call(this.items).forEach(function(item) {
          var revealer = document.createElement('div');
          revealer.className = 'grid__reveal';
          if (effectSettings.revealerOrigin != undefined) {
            revealer.style.transformOrigin = effectSettings.revealerOrigin;
          }
          if (effectSettings.revealerColor != undefined) {
            revealer.style.backgroundColor = effectSettings.revealerColor;
          }
          item.parentNode.appendChild(revealer);
        });
  
        var animeRevealerOpts = effectSettings.animeRevealerOpts;
        animeRevealerOpts.targets = this.el.querySelectorAll('.grid__reveal');
        animeRevealerOpts.begin = function(obj) {
          for (var i = 0, len = obj.animatables.length; i &lt; len; ++i) {
            obj.animatables[i].target.style.opacity = 1;
          }
        };
        anime.remove(animeRevealerOpts.targets);
        anime(animeRevealerOpts);
      }
  
      if (effectSettings.itemOverflowHidden) {
        [].slice.call(this.items).forEach(function(item) {
          item.parentNode.style.overflow = 'hidden';
        });
      }
  
      animeOpts.targets = effectSettings.sortTargetsFn &amp;&amp; typeof effectSettings.sortTargetsFn === 'function' ? [].slice.call(this.items).sort(effectSettings.sortTargetsFn) : this.items;
      anime.remove(animeOpts.targets);
      anime(animeOpts);
    };
  
    GridLoaderFx.prototype._resetStyles = function() {
      this.el.style.WebkitPerspective = this.el.style.perspective = 'none';
      [].slice.call(this.items).forEach(function(item) {
        var gItem = item.parentNode;
        item.style.opacity = 0;
        item.style.WebkitTransformOrigin = item.style.transformOrigin = '50% 50%';
        item.style.transform = 'none';
  
        var svg = item.parentNode.querySelector('svg.grid__deco');
        if (svg) {
          gItem.removeChild(svg);
        }
  
        var revealer = item.parentNode.querySelector('.grid__reveal');
        if (revealer) {
          gItem.removeChild(revealer);
        }
  
        gItem.style.overflow = '';
      });
    };
  
    window.GridLoaderFx = GridLoaderFx;
  
    var body = document.body,
      grids = [].slice.call(document.querySelectorAll('.grid')),
      masonry = [],
      currentGrid = 0,
      // Switch grid radio buttons.
      switchGridCtrls = [].slice.call(document.querySelectorAll('.control__radio')),
      // Choose effect buttons.
      fxCtrls = [].slice.call(document.querySelectorAll('.control--effects &gt; .control__btn')),
      // The GridLoaderFx instances.
      loaders = [],
      loadingTimeout;
  
    function init() {
      // Preload images
      imagesLoaded(body, function() {
        // Initialize Masonry on each grid.
        grids.forEach(function(grid) {
          var m = new Masonry(grid, {
            itemSelector: '.grid__item',
            columnWidth: '.grid__sizer',
            percentPosition: true,
            transitionDuration: 0
          });
          masonry.push(m);
          // Hide the grid.
          grid.classList.add('grid--hidden');
          // Init GridLoaderFx.
          loaders.push(new GridLoaderFx(grid));
        });
  
        // Show current grid.
        grids[currentGrid].classList.remove('grid--hidden');
        // Init/Bind events.
        initEvents();
        // Remove loading class from body
        body.classList.remove('loading');
        loaders[currentGrid]._render('Shu');
      });
    }
  
    function initEvents() {
      // Switching grids radio buttons.
      switchGridCtrls.forEach(function(ctrl) {
        ctrl.addEventListener('click', switchGrid);
      });
      // Effect selection.
      fxCtrls.forEach(function(ctrl) {
        ctrl.addEventListener('click', applyFx);
      });
    }
  
  
    function applyFx(ev) {
      // Simulate loading grid to show the effect.
      clearTimeout(loadingTimeout);
      grids[currentGrid].classList.add('grid--loading');
  
      loadingTimeout = setTimeout(function() {
        grids[currentGrid].classList.remove('grid--loading');
  
        // Apply effect.
        loaders[currentGrid]._render(ev.target.getAttribute('data-fx'));
      }, 500);
    }
  
    init();
  
  })(window);</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.js .loading::before,
  .js .loading::after {
    content: '';
    position: fixed;
    z-index: 1000;
  }
  
  .loading::before {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #2c2d31;
  }
  
  .loading::after {
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    margin: -20px 0 0 -20px;
    border: 8px solid #383a41;
    border-bottom-color: #565963;
    border-radius: 50%;
    animation: animLoader 0.8s linear infinite forwards;
  }
  
  @keyframes animLoader {
    to {
      transform: rotate(360deg);
    }
  }
  
  a {
    text-decoration: none;
    color: #f2f2f2;
    outline: none;
  }
  
  .hidden {
    position: absolute;
    overflow: hidden;
    width: 0;
    height: 0;
    pointer-events: none;
  }
  
  
  /* Icons */
  
  .content--side {
    position: relative;
    z-index: 100;
    width: 15vw;
    min-width: 130px;
    max-height: 100vh;
    padding: 0 1em;
    order: 2;
  }
  
  .content--center {
    flex: 1;
    max-width: 100vw;
  }
  
  .content--related {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
    padding: 8em 1em 3em;
    text-align: center;
    order: 5;
  }
  
  .media-related {
    width: 100%;
  }
  
  .media-item {
    padding: 1em;
  }
  
  .media-item__img {
    max-width: 100%;
    /*opacity: 0.7;*/
    /*transition: opacity 0.3s;*/
  }
  
  .media-item:hover .media-item__img,
  .media-item:focus .media-item__img {
    opacity: 1;
  }
  
  .media-item__title {
    font-size: 1em;
    max-width: 220px;
    padding: 0.5em;
    margin: 0 auto;
  }
  
  @keyframes octocat-wave {
    0%,
    100% {
      transform: rotate(0);
    }
    20%,
    60% {
      transform: rotate(-25deg);
    }
    40%,
    80% {
      transform: rotate(10deg);
    }
  }
  
  
  /* Grid */
  
  .grid {
    position: relative;
    z-index: 1;
    display: block;
    margin: 2% 5%;
  }
  
  .grid--hidden {
    position: fixed !important;
    z-index: 1;
    top: 0;
    left: 0;
    width: 100%;
    pointer-events: none;
    opacity: 0;
  }
  
  .js .grid--loading::before,
  .js .grid--loading::after {
    content: '';
    z-index: 1000;
  }
  
  .js .grid--loading::before {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: #2c2d31;
  }
  
  .js .grid--loading::after {
    position: absolute;
    top: calc(25vh - 20px);
    left: 50%;
    width: 40px;
    height: 40px;
    margin: 0 0 0 -20px;
    border: 8px solid #383a41;
    border-bottom-color: #565963;
    border-radius: 50%;
    animation: animLoader 0.8s linear forwards infinite;
  }
  
  .grid__sizer {
    margin-bottom: 0 !important;
  }
  
  .grid__link,
  .grid__img {
    display: block;
  }
  
  .grid__img {
    width: 100%;
  }
  
  .grid__deco {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
  }
  
  .grid__deco path {
    fill: none;
    stroke: #fff;
    stroke-width: 2px;
  }
  
  .grid__reveal {
    position: absolute;
    z-index: 50;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    opacity: 0;
    background-color: #2c2d31;
  }
  
  .grid__item {}
  
  .grid__item:hover&gt;.cm-pic-author {
    opacity: 1;
  }
  
  .grid__item:hover&gt;.cm-pic-social {
    opacity: 1;
  }
  
  .cm-pic-social {
    transition: opacity 0.6s ease-in-out;
    position: absolute;
    right: 10px;
    top: 10px;
    opacity: 0;
  }
  
  .cm-pic-social a {
    color: #ffffff;
    font-family: 'Roboto', sans-serif;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
    font-size: .9em;
    text-decoration: none;
  }
  
  .cm-pic-social a:not(:last-child) {
    margin-right: 1em;
  }
  
  .cm-pic-author {
    transition: opacity 0.6s ease-in-out;
    position: absolute;
    left: 10px;
    bottom: 10px;
    opacity: 0;
  }
  
  .cm-pic-author a {
    font-family: 'Roboto', sans-serif;
    font-size: .9em;
    text-decoration: none;
    color: #ffffff;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
  }
  
  .cm-pic-author a img {
    width: 35px;
    height: 35px;
    object-position: center;
    object-fit: cover;
    border: 1px solid #ffffff;
    -webkit-border-radius: 50%;
    -moz-border-radius: 50%;
    border-radius: 50%;
    margin-right: 10px;
  }
  
  .grid .grid__item,
  .grid .grid__sizer {
    width: calc(100% - 20px);
    margin: 0 10px 20px;
  }
  
  @media only screen and (min-width: 576px) {
    .grid .grid__item,
    .grid .grid__sizer {
      width: calc((100% / 2) - 20px);
      margin: 0 10px 20px;
    }
  }
  
  
  /* min-width 1200px, large screens */
  
  @media only screen and (min-width: 1200px) {
    .grid .grid__item,
    .grid .grid__sizer {
      width: calc((100% / 3) - 20px);
      margin: 0 10px 20px;
    }
  }
  
  
  /* min-width 1500px, xlarge screens */
  
  @media only screen and (min-width: 1500px) {
    /* Grid types */
    .grid-masonry .grid__item,
    .grid-masonry .grid__sizer {
      width: calc(25% - 20px);
      margin: 0 10px 20px;
    }
  }
  
  
  /* min-width 1800px, xlarge screens */
  
  @media only screen and (min-width: 1800px) {
    /* Grid types */
    .grid-masonry .grid__item,
    .grid-masonry .grid__sizer {
      width: calc(20% - 20px);
      margin: 0 10px 20px;
    }
  }
  
  
  /*!* min-width 2400px, xlarge screens 5k*!*/
  
  
  /*@media only screen and (min-width: 2400px){*/
  
  
  /*!* Grid types *!*/
  
  
  /*.grid-masonry .grid__item,*/
  
  
  /*.grid-masonry .grid__sizer {*/
  
  
  /*width: calc(16.666666% - 20px);*/
  
  
  /*margin: 0 10px 20px;*/
  
  
  /*}*/
  
  
  /*}*/</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/4.2.2/masonry.pkgd.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"&gt;&lt;/script&gt;
  &lt;div class="content content--center"&gt;
    &lt;div class="grid grid-masonry"&gt;
      &lt;div class="grid__sizer"&gt;&lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="image-details.html"&gt;
          &lt;img class="grid__img" src="https://i.imgur.com/dCFlYyG.jpg" alt="Some image" /&gt;
        &lt;/a&gt;
  
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href="personal-profile-follow.html"&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
  
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/Zneml4H.jpg" alt="Some image" /&gt;&lt;/a&gt;
  
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
  
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/H4bbqpA.jpg" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/9Q9pgmR.jpg" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="https://i.imgur.com/9Q9pgmR.jpg" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://picsum.photos/600/800" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="image-details.html"&gt;
          &lt;img class="grid__img" src="https://i.imgur.com/dCFlYyG.jpg" alt="Some image" /&gt;
        &lt;/a&gt;
  
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href="personal-profile-follow.html"&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
  
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/Zneml4H.jpg" alt="Some image" /&gt;&lt;/a&gt;
  
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
  
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/H4bbqpA.jpg" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://i.imgur.com/9Q9pgmR.jpg" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="https://i.imgur.com/9Q9pgmR.jpg" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="grid__item"&gt;
        &lt;a class="grid__link" href="#"&gt;&lt;img class="grid__img" src="https://picsum.photos/600/800" alt="Some image" /&gt;&lt;/a&gt;
        &lt;div class="cm-pic-social d-flex"&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/add.svg" alt=""&gt;&lt;/span&gt; Collection&lt;/a&gt;
          &lt;a href=""&gt;&lt;span&gt;&lt;img width="16px" src="images/love.svg" alt=""&gt;&lt;/span&gt; 50&lt;/a&gt;
        &lt;/div&gt;
  
        &lt;div class="cm-pic-author d-flex"&gt;
          &lt;a href=""&gt;&lt;img src="images/author@2x.png" alt=""&gt;J. Alexa&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;
  
    &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Now I am trying to implement it as a vue component so that I can render on any view page.</p>
  
  <p>Thank you</p>