繁体   English   中英

使用 Masonry.JS 和 Vue.JS

[英]Using Masonry.JS and Vue.JS

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

我想这样做的vue 方式是使用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>

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

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

正如我所看到的,大多数像 vue 这样的 mv* 框架保持 DOM 元素(视图)与 js(模型)同步,另一方面,像 masonry 这样的框架只需要有效的 DOM 就可以工作。 所以,棘手的部分是在 DOM 发生变化时告诉另一个人。

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

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 更新后调用的。 这是一个工作小提琴

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM