final effect
Responsive Evenly Arranged
Implementation ideas
The overall idea is to set the parent layout of the traversing elements to flex, and set justify-content to space-around, but at this time, if the last line is different (less than) from the number evenly distributed above, then evenly distributed in the play will appear , instead of aligning to the left as in the picture above. As for why the justify-content is not set to start, it is because if it is set to start, there is a high probability that there will be blanks on the right side, resulting in uneven distribution on both sides, which will affect the experience.
My solution here is to monitor the changes of the screen through the resize event of the window. When initializing the page, first calculate how many lines will be evenly arranged in the screen of the current width according to the width of the arranged elements, and then calculate the last line. There are several elements, so at this time, we subtract the number of the last row from the average number of each row, which is the number we need to fill in. Here, the blank placeholder elements are filled.
Implementation code
Photos.view:
<script setup>
import {
Plus, Search, UploadFilled } from '@element-plus/icons-vue';
import {
onMounted, reactive, ref } from 'vue';
const imageList = reactive(["https://www.devcat.cn/res/img/avatar.png","https://www.devcat.cn/res/img/smart-index.png","https://www.devcat.cn/res/img/avatar.png"])
const subCount = ref(0)
const initList = () => {
let count = parseInt((window.innerWidth-10) / 220)
subCount.value = count - (18 - count*(parseInt(18 / count)))
}
onMounted(()=>{
initList()
window.addEventListener('resize',()=>{
initList()
})
})
</script>
<template>
<main>
<div class="toolBar">
<el-input :suffix-icon="Search" placeholder="关键字搜索" style="width: 300px;"></el-input>
<el-button :icon="Plus" type="default" style="margin-left:10px;">新建相册</el-button>
<el-button :icon="UploadFilled" type="primary" style="margin-left:10px;">上传图片</el-button>
</div>
<div class="photoBox">
<div class="photoItem" v-for="item in 18" :key="item">
<el-image :initial-index="item-1" :preview-src-list="imageList" loading="lazy" style="width:200px; height:200px" fit="contain" src="https://www.devcat.cn/res/img/avatar.png"></el-image>
<div class="info">avatar{
{ item }}.png</div>
</div>
<div style="width: 200px; height: 200px; margin: 10px;" v-for="item in subCount" :key="item"></div>
</div>
</main>
</template>
<style scoped>
main{
padding: 10px;
}
.toolBar{
border-bottom: 1px solid #bbb;
padding-bottom: 10px;
}
.photoBox{
width: calc(100% - 20px);
display: flex;
justify-content: space-around;
flex-wrap: wrap;
padding: 10px;
}
.photoItem{
margin: 10px;
cursor: pointer;
}
.info{
text-align: center;
color: #444;
}
.helpLayout{
width: auto;
}
</style>
The above is only a solution for this kind of demand, if it is useful ===>** like + bookmark**