Masonry.js不鼓掌布局

时间:2018-02-07 02:51:37

标签: javascript laravel vue.js masonry

我正在使用Laravel,VueJS和Masonry.js库创建一个动态画廊,我面临着一个奇怪的问题。

我在VueJS模板中有这个:

<template lang="html">
  <div id="uploads-grid">
    <div class="grid" ref="grid">

      <!-- GRID START -->

      <div class="grid-item white-outline" v-for="(bg, index) in bgs" :style="'width:' + wd + 'px;height:' + hg[index] + 'px;'">
        <img :src="'/storage/users/1/photos/1/' + bg.photo" :width="wd" :height="hg[index]">
      </div>

      <!-- GRID END -->

    </div>
  </div>
</template>

这就是我获取图像的方式:

<script>

import Masonry from 'masonry-layout';

export default {
  data() {
    return {
      bgs: [],
      wd: '300',
      hg: []
    }
  },
  methods: {
    getPhotos() {
      var url = '/photos/get'
      axios.get(url).then(r => {
        this.bgs = r.data
        for (var i = 0; i < r.data.length; i++) {
          var factor = r.data[i].width / 300
          var resizeHeight = Math.floor(r.data[i].height / factor)
          this.hg.push(resizeHeight)
        }
      });
    }
  },
  mounted() {
    let $masonry = new Masonry(this.$refs.grid, {
      itemSelector: '.grid-item',
      columnWidth: 300,
      isFitWidth: true
    });
  },
  created() {
    this.getPhotos()
  }
}
</script>

问题在于每张图片都显示在最后一张图片之后。

无论哪种方式,这段代码都可以正常使用:

<template lang="html">
  <div id="uploads-grid">
    <div class="grid" ref="grid">

      <!-- GRID START -->

      <div class="grid-item white-outline" v-for="(bg, index) in bgs" :style="'width:' + wd[index] + 'px;height:' + hg[index] + 'px;'">
        <img :src="bg">
      </div>

      <!-- GRID END -->

    </div>
  </div>
</template>

<script>

import Masonry from 'masonry-layout';

export default {
  data() {
    return {
      bgs: [],
      wd: [],
      hg: []
    }
  },
  methods: {
    rndBg() {
      for (var i = 0; i < 20; i++) {
        var wd = 300
        var hg = Math.floor(Math.random() * 350) + 150
        var bgsrc = 'https://placehold.it/' + wd + 'x' + hg
        this.bgs.push(bgsrc)
        this.wd.push(wd)
        this.hg.push(hg)
      }
    }
  },
  mounted() {
    let $masonry = new Masonry(this.$refs.grid, {
      itemSelector: '.grid-item',
      columnWidth: 300,
      isFitWidth: true
    });
  },
  created() {
    this.rndBg()
  }
}
</script>

问题是我正在使用placeholdit虚拟图像,而不是我想要的那些......我不适合我。我使用相同的逻辑但是......是的,我无法让它工作。

1 个答案:

答案 0 :(得分:0)

要点:添加新图片后,您必须再次触发砌体。

砌体的工作原理是将固定位置,宽度等设置为元素。因此,每次添加/删除某些内容时,您应触发砌体重新计算并再次设置固定位置,宽度等...

e.g。 https://codesandbox.io/s/4xw830q1r4 components / Hello.vue

Observable<String> source = Observable.create(emitter -> {...});
Observable<String> source2 = source.subscribeOn(Schedulers.newThread())
<template> <div class="hello"> <button @click="addImg"> add img </button> <br/><br/> <div class="grid"> <div class="grid-item" v-for="img in imgs"> <img :src="img"> </div> </div> </div> </template> <script> import Masonry from 'masonry-layout'; export default { name: 'hello', data () { return { imgs:[ `https://unsplash.it/200/300/?random=${Math.random()}`, `https://unsplash.it/200/100/?random=${Math.random()}`, `https://unsplash.it/200/400/?random=${Math.random()}`, `https://unsplash.it/200/250/?random=${Math.random()}` ] } }, mounted() { this.triggerMasonry(); }, methods:{ triggerMasonry() { console.log('triggerMasonry'); var grid = document.querySelector('.grid'); var msnry = new Masonry( grid, { itemSelector: '.grid-item', columnWidth: 200 }); }, addImg(){ this.imgs.push(`https://unsplash.it/200/300/?random=${Math.random()}`); this.$nextTick(()=>{ this.triggerMasonry(); }); } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped lang="scss"> .grid { width: 100%; img { width: 100%; } } </style> 上的{p> triggerMasonry,以及添加新图片后的mounted

只有在将图片添加到DOM后,您还需要使用nextTicktriggerMasonry