产品详情页中经常需要把图片按照九宫格的形式展示,同时点击图片时能打开当前图片的预览。
页面结构
九宫格用到flex布局的对齐方式space-between, 可以均匀排列盒子中的每个元素。
flex-wrap: wrap;可以自动换行。
但当最后一行元素不能铺满时,会将元素中均分排列,效果并不是我们需要的。这时需要手动根据最后一行元素的个数补充几个空白盒子,来填满一行。
vue文件
<view class="proImg" wx:if="{{detail.pic}}">
<image wx:for="{{m1.toArray(detail.pic)}}" src="{{item}}" data-pic="{{item}}" catch:tap="imgClick" mode="aspectFill" />
<!-- 手动添加的空白盒子 -->
<view wx:for="{{m1.calculateOffset(detail.pic)}}" class="blankImgBox"></view>
</view>
<wxs module="m1">
function toArray(str) {
var arr = str.split(',')
return arr
}
function calculateOffset(str) {
var arrLength = str.split(',').length
return (arrLength % 3 === 0) ? 0 : (3 - (arrLength % 3));
}
module.exports.toArray = toArray
module.exports.calculateOffset = calculateOffset
</wxs>
函数 calculateOffset来计算补盒子的个数。
这个方法中使用了条件判断 (arrLength % 3 === 0) 来检查数组长度是否是三的倍数。
1、如果是三的倍数,返回值为 0,表示没有偏移。
2、如果不是三的倍数,使用 (3 - (arrLength % 3)) 计算出相对于三的倍数的偏移量。例如,对于长度为 7 的数组,它相对于3的倍数9的偏移量是 2。
其他倍数也是一样的计算逻辑,只需把3换成其他倍数即可。
如果需要图片不变形,需要给image设置mode: aspectFill。
aspectFill:保留中部 等比例变化
aspectFill 与 widthfix 都是保持宽高比不变
aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来。
也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
aspectFill保持图片的宽高比不会变形,让图片完全填满整个容器,类似于scaleToFill这种模式。
但是,scaleToFill会改变图片的宽高比,而aspectFill不会。
wxss文件
.proImg {
display: flex;
/* 自动换行 */
flex-wrap: wrap;
justify-content: space-between;
margin-top: 24rpx;
.blankImgBox {
width: 204rpx;
height: 204rpx;
}
image {
margin-bottom: 24rpx;
width: 204rpx;
height: 204rpx;
border-radius: var(--border-radius-s);
}
/* 最后一行的元素取消下边距 */
image:nth-last-child(-n+3) {
margin-bottom: 0;
}
}
点击图片预览
js文件
imgClick(e) {
let current = e.currentTarget.dataset.pic
let url = this.data.detail.pic.split(',')
// 图片预览
wx.previewImage({
current: current, //当前图片,string
urls: url, //imgUrl 必须是需要预览的图片链接列表,只有一张图片也需要是列表
})
}
在微信小程序中,wx.previewImage函数用于预览图片,可以将一组图片以轮播的方式展示给用户,并支持用户手势操作进行切换。
使用wx.previewImage函数需要传入一个参数对象,该对象包含以下属性:
1、current: String,必填,当前显示图片的链接/路径。
2、urls: Array,必填,需要预览的图片链接/路径列表。