使用Masonry.JS和Vue.JS

18

除了vue,我知道如何使用masonry.js。然而,我在vue框架内正确调用它并使其运作起来遇到了问题。我尝试在createdready中调用它,但似乎都无法正确形成网格。我该如何让它在这个框架内工作?哦,还有在此脚本之前我已经在html中调用了jquery。以下是我在组件内部的代码:

编辑:

我可以看到masonry通过JS分配高度并将项更改为绝对位置影响网格。然而,它没有正确地放置它们。它们被堆叠在彼此上方而不是像网格一样并排放置。 enter image description here

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

2
请澄清发生了什么。它什么也不做吗?它只部分工作吗?它会抛出错误吗? - ceejayoz
添加了更多信息和控制台图像。 - Ricki Moore
5个回答

9

在我看来,大多数像Vue这样的mv*框架会将DOM元素(视图)与js(模型)同步,而像砌体这样的框架只需要有效的DOM即可工作。因此,棘手的部分是告诉另一个何时DOM已更改。

因此,第一个变化是当Vue完成渲染所有DOM时,正如其他答案中提到的,我们在mounted生命周期钩子上收到通知,这是我们可以初始化砌体的地方。

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使用Vue.nextTick函数完成DOM更新后调用的。 这里有一个工作JSFiddle链接

8
我猜做这件事的vue方式是使用refs。只需在模板中的HTML元素上分配ref属性,并在mounted callback中使用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>

7

0

可能是垂直堆栈只是表示砌体不起作用(没有codepen/plunkr很难确定)。@riyaz-ali的想法是正确的。


1
这应该是一条注释,而不是一个答案。 - Souvik Ghosh

0

你必须在mounted()事件中调用masonry才能使其正常工作。 我在我的项目中使用它(与imagesloaded一起),它完美地工作。

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

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

我收到了“.masonry不是一个函数”的错误。 - gbertl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接