基于vue的固定高度图片瀑布流组件
<!--
@Description: pictureList 图库列表组件
@Author: sunyongwei
@Date: 2022-10-12
@Version: V1.0
-->
<template>
<div style="margin: 20px;">
<div style="display: flex;justify-content: space-between">
<div style="min-width: 20%;">
<div style="font-weight: bold;font-size: 16px;">
<span v-for="(item,index) in fullTitle">{{item}}
<span v-if="index<fullTitle.length-1">/ </span>
</span>
</div>
<div style="font-size: 10px;color: #767676;">{{list.length}}个文件,共{{(sizeTotle / 1024 / 1024).toFixed(3)}}GB</div>
</div>
<div>
</div>
</div>
<div v-if="rowList.length>0">
<div class="row" v-for="(row,index) in rowList" :key="index" style="min-width:1100px;">
<div class="img-box" v-for="img in row" :key="img.id" :style="{'width':img.width+'px','height':img.height+'px','margin':'0 '+ imgMargin+'px'}">
<img :src="img.url" :style="{'width':img.width+'px','height':img.height+'px'}" v-if="img.type == '1'"></img>
<img :src="img.cover" :style="{'width':img.width+'px','height':img.height+'px'}" v-if="img.type == '2'"></img>
</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'pictureList',
props:{
list:{
type:Array,
default() {
return []
}
},
fullTitle:{
type:Array,
default() {
return ''
}
},
imgHeight: {
type: Number,
default: 220
},
imgMargin: {
type: Number,
default: 5
},
button: {
type: Boolean,
default: true
},
},
data () {
return {
pictureList:[],
screenWidth:1000,
sizeTotle:0
}
},
watch:{
list(){
this.sizeTotle = 0
this.initList()
if(this.list.length==0)return
this.list.forEach(e=>{
this.sizeTotle += e.size
})
},
},
computed: {
rowList () {
return this.waterfallHandler()
}
},
mounted() {
this.screenWidth = document.body.clientWidth;
window.onresize = () => {
return (() => {
this.screenWidth = document.body.clientWidth;
this.waterfallHandler()
})();
};
let that = this
setTimeout(function(){
that.screenWidth = document.body.clientWidth-1;
that.waterfallHandler()
},500)
},
created() {
if(this.list.length==0)return
this.initList()
this.list.forEach(e=>{
this.sizeTotle += e.size
})
},
methods: {
initList(){
this.pictureList = []
if(this.list.length==0)return
this.list.forEach(e=>{
let item = e
var img = new Image();
img.src = e.type == '1' ? item.url : item.cover;
img.onload = function(){
item.width = img.width
item.height = img.height
}
this.pictureList.push(item)
})
},
onChange(){
this.$emit('onChange')
},
waterfallHandler() {
if(this.list.length==0)return []
const newList = []
const screenWidth = Number(this.screenWidth) > 1000 ? Number(this.screenWidth) - 500 : 1000
const rowHeight = this.imgHeight
let arrRow = []
let imgsData = []
imgsData = JSON.parse(JSON.stringify(this.pictureList))
for (let i = 0; i < imgsData.length; i++) {
const item = imgsData[i]
item.ratio = Number(item.width) / Number(item.height)
const newWidth = parseInt(item.ratio * rowHeight)
item.width = newWidth
item.height = rowHeight
let totalWidth = 0
arrRow.push(item)
for (let i = 0; i < arrRow.length; i++) {
totalWidth += arrRow[i].width
}
if (totalWidth > screenWidth) {
const lastImg = arrRow.pop()
totalWidth -= lastImg.width
const newHeight = screenWidth * rowHeight / totalWidth
const marginSpace = (arrRow.length - 1) * (this.imgMargin / 20)
for (let i = 0; i < arrRow.length; i++) {
arrRow[i].width = newHeight * arrRow[i].ratio - marginSpace
arrRow[i].height = newHeight - (marginSpace / arrRow[i].ratio)
}
newList.push(arrRow)
arrRow = []
arrRow.push(lastImg)
}
}
let tmp = 0
for (let i = 0; i < newList.length; i++) {
tmp += newList[i].length
}
const lastRow = []
for (let i = tmp; i < imgsData.length; i++) {
imgsData[i].height = rowHeight
imgsData[i].width = imgsData[i].ratio * rowHeight
lastRow.push(imgsData[i])
}
newList.push(lastRow)
return newList
}
}
}
</script>
<style scoped >
.popover-button{
line-height: 40px;
padding:0 20px;
color: #000;
border-bottom: 1px solid #D8D8D8;
}
.popover-button:hover{
cursor: pointer;
color: #1890FF;
border-bottom: 1px solid #1890FF;
}
.row {
margin-top: 5px;
display: flex;
}
a {
text-align: center;
}
.img-box {
transition: all 0.5s;
}
.img-box>img {
transition: all 0.5s;
}
.img-box:hover {
transform: scale(1.05);
}
.img-box:hover>img {
transform: scale(1.05);
}
</style>
![在这里插入图片描述](https://img-blog.csdnimg.cn/641d76b7a4334bd0b4cd427fa1314f54.png)