框架
以下用的是双重for循环,且第二层循环需要做split(',')处理
<el-timeline v-if="photosList.length>0">
<el-timeline-item v-for="(item, index) in photosList" :key="index" :timestamp="item.createTime"
placement="top"
>
<template slot="timestamp">
{{ item.timestamp }}
</template>
<div>
<div v-if="item.handbookImages">
<div class="img-content">
<div v-for="(image,imgIndex) in displayImages(item.handbookImages)"
:key="imgIndex"
class="demo-image__preview"
:class="{
'single-image': displayImages(item.handbookImages).length === 1,
'two-images':displayImages(item.handbookImages).length === 2,
'three-images': displayImages(item.handbookImages).length >= 3
}"
>
<el-image
class="lazy"
:src="baseUrl + image"
fit="cover"
lazy
@click="openImage(imgIndex,item.handbookImages)"
>
</el-image>
<!-- 只在最后一张图片上显示剩余图片-->
<span
v-if="imgIndex === displayImages(item.handbookImages).length - 1 && remainingImagesCount(item.handbookImages) > 0"
class="more-indicator"
@click="openImage(imgIndex,item.handbookImages)"
>
+{{ remainingImagesCount(item.handbookImages) }}
</span>
</div>
</div>
</div>
</el-timeline-item>
</el-timeline>
<!--点击图片看大图的预览效果-->
<van-image-preview
v-model="show"
:images="images"
>
</van-image-preview>
imgIndex === displayImages(item.handbookImages).length - 1,它是用来判断只在最后一个图片上方显示剩余图片数量样式,不加的话,所有图片上方都会显示剩余图片数量。
displayImages(item.handbookImages)是方法,传入数据,会在js部分有处理
css
做动态样式,用于判断当前数组中的图片是几张,下面是css代码
/*最新动态图片样式*/
.img-content {
display: flex;
flex-wrap: wrap;
}
/*每一个图片外面的div盒子,用来做图片的公共样式*/
.demo-image__preview {
margin: 2px;
border-radius: 10px;
overflow: hidden;
position: relative; /* 用于定位剩余图片数量的显示 */
}
.single-image {
width: 100%; /* 当只有一张图片时,占据整行 */
}
.two-images {
/*flex-basis: calc(50% - 10px);*/ /* 减去间距的一半 */
width: calc(76vw / 2);
height: calc(76vw / 2);
margin-left: 5px;
}
.three-images {
/* flex-basis: calc(33.3333% - 6.6667px);*/ /* 减去间距的三分之一 */
width: calc(76vw / 3);
height: calc(76vw / 3);
}
/*超过九张图片时,第九张图片上方的样式*/
.more-indicator {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.57);
font-size: 34px;
color: #a5a5a5;
}
/* 确保最后一个元素在只有两个图片时也有正确的间距 */
.two-images:nth-last-child(2) {
margin-right: 0; /* 移除右边距 */
}
/*image图片样式处理*/
.lazy {
width: 100%;
height: 100%;
object-fit: cover; /* 保持图片的宽高比,同时填充整个容器 */
background-color: #f4f4f4;
display: block;
}
js部分
// 获取前九张图片
displayImages(imagesStr) {
if (imagesStr !== null) {
imagesStr = imagesStr.split(',')
// 将逗号分隔的字符串转化为数组,并返回前9个元素
return imagesStr.slice(0, 9)
}
},
// 获取九宫格未展示图片数量
remainingImagesCount(images) {
if (images) {
images = images.split(',')
// 计算剩余的图片数量
return images.length - 9
}
},
// 点击图片看大图
openImage(index, imgContent) {
this.images = []
if (imgContent) {
this.show = true
const imgArry = imgContent.split(',') // 把路径字符串分成数组
this.images = imgArry.map(item => this.baseUrl + item) // 把baseUrl加到路径上
// 使用 splice 方法移除并返回指定索引处的元素
const itemTomMove = this.images.splice(index, 1)[0]
// 使用 unshift 方法将移除的元素插入到数组的开头
this.images.unshift(itemTomMove)
return this.images
} else {
this.image = []
}
},
效果图
一个效果图
两个效果图
三个效果图
九个以上效果图
以上仅部分代码,逻辑是通的,data数据和获取接口数据省略