【发布时间】:2021-08-05 11:44:12
【问题描述】:
我的网站上有一个页面,我在其中展示了一些砖石布局的卡片。
它是在 Vue 3 中实现的,我希望布局能够适应容器的子高度。
布局从上到下,从左到右。就像图片显示的那样:
为了实现这一点,我使用order CSS 属性和弹性框将卡片分成不同的列。
但是,要使其正常工作,父容器需要具有固定高度。
我希望这是确保所有卡片都适合的最小高度,即布局中最长列的确切高度。
我最初尝试将容器的高度设置为 0,然后根据卡片的高度对其进行更新,但是,这不是很好,而且真的很笨拙。
<template>
<section class="container" :style="{ height: containerHeight }">
<project-card v-for="i in projects.length" :key="i" :project="projects[i - 1]"
:style="{ order: (i - 1) % numberColumns + 1, width: (100 / numberColumns) - 1.5 + '%' }"
:ref="setProjectCardRef">
</project-card>
<span v-for="i in numberColumns - 1" :key="i" :style="{ order: i }" class="item break"></span>
</section>
</template>
<script>
import Projects from "@/api/Projects";
import ProjectCard from "@/components/ProjectCard";
export default {
name: "Projects",
components: {
"project-card": ProjectCard,
},
data() {
return {
projects: [],
projectCardsRefs: [],
windowWidth: window.innerWidth,
containerHeight: "100%"
}
},
mounted() {
this.getData();
window.addEventListener('resize', () => {
this.windowWidth = window.innerWidth
})
},
methods: {
getData() {
Projects.list().then((response) => {
for (let project of response.data)
project.image_url = process.env.VUE_APP_API_ENDPOINT + project.image_url;
this.projects = response.data;
});
},
setProjectCardRef(el) {
if (!this.projectCardsRefs.includes(el))
this.projectCardsRefs.push(el)
}
},
computed: {
numberColumns() {
return Math.round(this.windowWidth / 400)
},
},
async updated() {
await new Promise(r => setTimeout(r, 200));
let heights = Array(this.numberColumns).fill(0)
for (let i = 0; i < this.projectCardsRefs.length; i++) {
const style = this.projectCardsRefs[i].$el.currentStyle || window.getComputedStyle(this.projectCardsRefs[i].$el);
const marginTop = parseInt(style.marginTop.match(/\d+/g)[0]);
const height = parseFloat(style.height.match(/\d+(.\d+)?/g)[0]);
heights[i % this.numberColumns] += height + marginTop
}
this.containerHeight = 40 + Math.max(...heights) + "px";
}
}
</script>
<style scoped>
.container {
@apply flex flex-col flex-wrap space-y-6;
}
.break {
@apply mx-3 w-0;
flex-basis: 100%;
}
</style>
如何以更灵敏的方式根据其子级设置容器的高度?
【问题讨论】:
-
更新了问题@Paulie_D
-
定义“更具响应性”,不,flexbox 需要定义的高度。我建议你真的需要 masonry.js。
-
你可以看到它目前是如何实现的here。一开始有一个短暂的时刻,当它仍在更新容器并且内容正在加载时,卡片会在其中跳来跳去。当页面调整大小时也会发生这种情况,并且并不总是正确计算高度,有时会与必要的高度相差一些像素并使内容不合适