今天逛掘金的时候,突然逛到了瀑布流的推送,故进行学习
columns布局
该方式仅适合数据固定,且从下往上,再左往右展示的情况,那我们仅需要依赖CSS就可以完成
<div class="container">
<div class="item">
<img src="./imgs/1.jpg"/>
我是一段文字用于占位
</div>
<div class="item">
<img src="./imgs/2.jpg"/>
我是一段文字用于占位,如果我特别长的话会怎么样,说实话我也不知道,这一切还要看效果
</div>
<div class="item">
<img src="./imgs/3.jpg"/>
我是一段文字用于占位
</div>
.container{
columns: 2;
column-gap: 10px;
}
.container .item{
margin-bottom:10px;
border:1px solid #ccc;
break-inside: avoid;
}
.item img{
width:100%;
}
Grid实现
小知识,~~按位非运算符两次之后可以直接取整数部分
import List from './list.json'
import { onMounted, ref } from 'vue'
const imgsRef = ref(null)
// 动态计算高度
onMounted(() => {
Array.from(imgsRef.value as any).forEach((img: HTMLImageElement) => {
let src = img.getAttribute('url')! // 非空断言
let image = new Image()
image.src = src //得到图片的地址
// 当前宽度, 被grid自动分配的宽度 假设总430,那么算间距现在一份可能是135
let width = img.width
image.onload = () => {
let w = image.width // 图片宽度
let h = image.height // 图片高度
// 计算需要的高度比,用加载好图片后的高度 * 原来的宽度 除 现在的宽度
// todo 其实直接用图片高度也行的, 不知道为什么这里要计算
// 假设图片 300 * 240, 240 * 300 / 135
let height = Math.round((h * width) / w)
img.src = src
// 设置跨越几个网格 即份数
img.style.gridRowEnd = `span ${~~(height / 10)}`
}
})
})
<div class="container">
<img
v-for="i in List"
:url="i.img"
:key="i.id"
class="item"
ref="imgsRef"
width="100%"
height="100%" />
</div>
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; // 分为3列
column-gap: 5px; // 列间距5px
grid-auto-rows: 10px;
.item {
grid-row-start: auto;
}
}
这里的核心就是grid-auto-rows和grid-row-start
,让网格开始跨越份数自动计算,通过动态计算图片高度,给予网格结束位置的跨越份数
Flex实现
不同于Grid
, Flex需要手动控制列的布局(Flex是一维布局),还需要控制数据的手动拼接,核心还是CSS的布局
布局
<div class="container">
<div class="col">
<img v-for="i in List1" :src="i.img" :key="i.id" class="item" />
</div>
<div class="col">
<img v-for="i in List2" :src="i.img" :key="i.id" class="item" />
</div>
</div>
JS逻辑
import List from './list.json'
import { ref } from 'vue'
const List1 = ref<any[]>([])
const List2 = ref<any[]>([])
const i = ref(0)
while (i.value < List.length) {
List1.value.push(List[i.value++])
if (i.value < List.length) List2.value.push(List[i.value++])
}
样式
.container {
display: flex;
flex-direction: row;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
.item {
width: 100%;
margin-bottom: 10px;
}
}
总结
三种方案来看,如果要结合实际业务使用还是推荐Flex布局,大多数情况下我们都要去计算最小高度列来进行数据插入.
说个题外话,要好好学习下Grid布局了,近期就把书肝完