Использование Masonry.JS и Vue.JS

Я знаю, как использовать masonry.js помимо vue. Тем не менее, у меня возникла проблема с тем, чтобы он функционировал и корректно назывался внутри рамки vue. Я назвал его внутри созданного или готового, но ни один из них не получил правильную форму сетки. Как я могу заставить это работать внутри рамки? О, и у меня есть jquery, вызванный в html до этого script. Вот что у меня внутри компонента:

Edit:

Я вижу, что кладка выполняет сетку, назначая ее высоту с помощью JS и изменяя позиции на абсолютную позицию. Тем не менее, он не размещает их правильно. Его укладка их поверх каждой стороны вместо боковой стороны, как и в сетке. введите описание изображения здесь

<template>
  <div class="projects--container">
    <div class="inner-section inner--options">
        <div class="grid">
            <div class="grid-item"></div>
            <div class="grid-item"></div>
            <div class="grid-item"></div>
        </div>
    </div>
  </div>
</template>

<script>
 export default{
    ready: function () {
        this.mason();
    },
     data: function () {
         return {
             options: [
                 {
                   option: 'projects',
                     phrase: 'for clients',
                     slogan: 'slogan...'
                 },
                 {
                     option: 'sides',
                     phrase: 'for us',
                     slogan: 'we love what we make'
                 },
                 {
                     option: 'moments',
                     phrase: 'with the crew'
                 }
             ]
         }
     },
     methods: {
         revert: function () {
             this.$dispatch('return-home', true)
         },
         mason: function () {
             var $grid = $('.grid').masonry({
                 itemSelector: '.grid-item',
                 columnWidth: 250
             });
             $grid.masonry('layout');
         }
     },
     events: {
         'option-select': function (option) {
         }
     }

 }
</script>

Ответы

Ответ 1

Я предполагаю, что vue-way делает это с помощью refs. Просто присвойте свойство ref вашему элементу html внутри шаблона и получите доступ к нему с помощью свойства экземпляра vm. $Ref внутри установленный обратный вызов.

Пример кода может выглядеть так:

<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>

Ответ 2

В Vue2 нет такой вещи, как крючок жизненного цикла ready. Вместо этого крючок жизненного цикла mounted запускается после того, как экземпляр "готов" так, как вы думаете.

Ссылка: https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

Ответ 3

Как я увидел, большинство mv * -структур, таких как vue, сохраняют элементы DOM (представление) в синхронизации с js (model), с другой стороны, фреймворки, такие как кладка, просто нуждаются в действительной DOM для работы. Итак, сложная часть - рассказать друг другу, когда DOM изменился.

Итак, первое изменение - это когда vue закончил визуализацию всех DOM, как упоминалось в других ответах, мы уведомлены о крюке mounted lifecycle, здесь мы можем инициализировать кладку

mounted() {
    let grid = document.querySelector('.grid');
    this.msnry = new Masonry(grid, {
        columnWidth: 25
    });
},

В любом другом изменении нашего представления также необходимо также обновить кладку, если вы измените размер элементов, используйте метод layout(), если вы добавляете или удаляете элементы, используйте метод reloadItems()

    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();
            });
        }
    }

Обратите внимание, что эти методы вызывается после того, как vue завершил обновление DOM с помощью функции Vue.nextTick. Вот рабочая скрипка.

Ответ 4

Возможно, вертикальный стек указывает на то, что кладка не работает (трудно сказать без кода /plunkr ). @riyaz-ali имеет правильную идею, хотя.

Ответ 5

вы должны вызвать кладку внутри события mounted(), чтобы она работала. я использую это в своем проекте (с изображениями) его работу отлично

massonryApply (container, context, selector) {
  container = $(`#${container}`)
  const $grid = container.imagesLoaded(function () {
    $grid.masonry({
      itemSelector: `.${selector}`,
      percentPosition: true,
      columnWidth: `.${selector}`
    })

    $grid.masonry('reloadItems')
  })
}