vue3组合式api+ts实现瀑布流布局.

 将以下代码写成一个组件即可使用

<div class="waterfall" ref="waterfall">
     <img class="waterfall-image" :src="item" alt="" v-for="(item, index) in imageArr" @load="setPosition">
</div>
<script setup lang="ts">
import { ref, onMounted } from "vue"
// ********将下面的数组换成请求的接口数据既可,现在是测试图片地址
// 注意!!!!如果图片来源于请求使用watch监听imageArr不然会显示不出来
const imageArr = ref<string[]>([img1, img2, img3, img4, img5,img1, img2, img3, img4, img5,img1, img2, img3, img4, img5]) 
// 瀑布流父容器
const waterfall = ref<HTMLDivElement | null>(null)
// 图片的宽度
const imageWidth: number = 277
// 图片的列间距
const imageColMargin: number = 20
// 父容器的宽度
let parentWidth: number = 0
// 有几列图片
const imageCol: number[] = [];
// 开始布局
onMounted(() => {
    getImageCol();
})
//  父容器能容纳多少列
const getImageCol = (): void => {
    if (!waterfall.value) return;
    parentWidth = waterfall.value.getBoundingClientRect().width
    // 添加图片的列数高度
    for (let i = 0; i < Math.floor(parentWidth / imageWidth); i++) {
        imageCol.push(0)
    }
}
const setPosition = (e: Event): void => {
    const image = e.target as HTMLImageElement
    // 假设最小值为第0个
    let minIndex = 0;
    // 遍历数组并更新最小值及其索引
    for (let i = 1; i < imageCol.length; i++) {
        if (imageCol[i] < imageCol[minIndex]) {
            minIndex = i;
        }
    }
    // 设置图片的位置
    image.style.top = imageCol[minIndex] + 'px'
    // 他的left就是 图片的固定宽度加剩余宽度
    image.style.left = minIndex * ((parentWidth % imageWidth / (imageCol.length-1)) + imageWidth) + 'px'
    imageCol[minIndex] += image.clientHeight + imageColMargin
    // 最后设置父容器的坍塌高度
    if(!waterfall.value) return;
    waterfall.value.style.height = Math.max(...imageCol) + 'px'
}
///  瀑布流布局功能结束
</script>

注意waterfall-image的宽度要和js代码中的imageWidth一样 

// 使用scss或less
.waterfall {
    position: relative;
    .waterfall-image {
        position: absolute;
        width: 277px;
    }
}

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值