【问题标题】:Using Masonry.JS and Vue.JS使用 Masonry.JS 和 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>

【问题讨论】:

  • 请澄清发生了什么。它什么都不做吗?它是否部分工作?它会抛出错误吗?
  • 添加了更多信息和控制台图像。

标签: javascript jquery vue.js jquery-masonry


【解决方案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 不是函数
        猜你喜欢
        • 2016-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-03
        • 2016-01-29
        • 2012-04-03
        相关资源
        最近更新 更多