使用 Masonry.JS 和 Vue.JS

Posted

技术标签:

【中文标题】使用 Masonry.JS 和 Vue.JS【英文标题】:Using Masonry.JS and Vue.JS 【发布时间】:2016-10-28 00:45:11 【问题描述】:

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

编辑:

我可以看到砌体通过使用 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 元素,然后使用 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>

【讨论】:

【参考方案2】:

在 Vue2 中,没有 ready 生命周期钩子之类的东西。相反,mounted 生命周期钩子会在实例以您所想的方式“准备就绪”时触发。

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

【讨论】:

【参考方案3】:

正如我所见,像 vue 这样的大多数 mv* 框架都让 DOM 元素(视图)与 js(模型)保持同步,另一方面,像 masonry 这样的框架只需要有效的 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。

【讨论】:

【参考方案4】:

可能是垂直堆栈只是表明砌体不工作(没有 codepen/plunkr 很难判断)。不过@riyaz-ali 的想法是对的。

【讨论】:

这应该是评论而不是答案【参考方案5】:

您必须在 mounted() 事件中调用 masonry 才能使其工作。 我在我的项目中使用它(加载了图像)它的工作完美

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

    $grid.masonry('reloadItems')
  )

【讨论】:

我得到 .masonry 不是函数

以上是关于使用 Masonry.JS 和 Vue.JS的主要内容,如果未能解决你的问题,请参考以下文章

bootstrap+masonry.js写瀑布流

瀑布流网页布局+加载动画+固定加载页数

EmberJS View - 检测是不是所有子视图都已呈现

使用java加密和解密密码使用啥API和算法

如何使用 php 和 mysql 使用纬度和经度进行几何搜索

Cocoa - 为啥使用 NSInteger 和 CGFloat 而不是使用 int 和 float,或者总是使用 NSNumber?