使用Masonry.JS和Vue.JS

时间:2016-06-25 14:40:55

标签: javascript jquery vue.js jquery-masonry

我知道除了vue之外如何使用masonry.js。但是,我有问题让它运行并在vue框架内正确调用。我在创建或准备好的内部调用它,但似乎都没有正确形成网格。我怎样才能让这个在框架内工作?哦,我确实在此脚本之前的html中调用了jquery。这是我在组件中的内容:

编辑:

我可以看到砌体通过用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>

5 个答案:

答案 0 :(得分:8)

我猜这样做的 vue-way 就是使用refs。只需将 ref 属性分配给模板中的html元素,然后使用vm.$ref中的mounted callback实例属性访问它。

示例代码可能如下所示:

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

答案 1 :(得分:6)

在Vue2中,没有ready生命周期钩子这样的东西。相反,一旦实例以您认为的方式“准备好”,就会触发mounted生命周期钩子。

参考:https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

答案 2 :(得分:5)

正如我所看到的,大多数像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更新后调用这些方法。 这是working fiddle

答案 3 :(得分:0)

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

答案 4 :(得分:0)

你必须在mounted()事件中调用砌体才能使其正常工作。 我正在我的项目(带有imagesloaded)上使用它完美的工作

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

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