Masonry.js 未应用布局
Masonry.js not applaying layout
我正在使用 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 虚拟图像,而不是我想要的图像,所以...我不适合我。我正在使用相同的逻辑但是...是的,我无法让它工作。
要点:添加新图片后需要再次触发Masonry
Masonry 通过为元素设置固定位置、宽度等来工作。所以每当有东西是 added/removed 时,你应该触发 Masonry 重新计算并重新设置固定位置、宽度等...
例如https://codesandbox.io/s/4xw830q1r4 components/Hello.vue
<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>
triggerMasonry
mounted
,以及 triggerMasonry
添加新图像后。
您还需要使用 nextTick 到 triggerMasonry
只有在图像添加到 DOM 之后。
我正在使用 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 虚拟图像,而不是我想要的图像,所以...我不适合我。我正在使用相同的逻辑但是...是的,我无法让它工作。
要点:添加新图片后需要再次触发Masonry
Masonry 通过为元素设置固定位置、宽度等来工作。所以每当有东西是 added/removed 时,你应该触发 Masonry 重新计算并重新设置固定位置、宽度等...
例如https://codesandbox.io/s/4xw830q1r4 components/Hello.vue
<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>
triggerMasonry
mounted
,以及 triggerMasonry
添加新图像后。
您还需要使用 nextTick 到 triggerMasonry
只有在图像添加到 DOM 之后。