上图是完成后的效果。在做整个需求的时候,是有三种方案摆在面前的,一是用 flex,二是 grid, 三是 element-plus 里的 layout 布局。前者是一维数组,不管是后期维护代码还是动态增加区域都有很好的可维护性和延展性,基本上只要维护数据就好了;后两者是二维数组,维护起来还要改样式就感觉挺麻烦的,关键是对自适应换行这一块没有很简便的解决办法(也有可能是自己不熟悉)。拿三种做了测试,从实现效果来说,自然是后两者最好,但不能自适应换行。flex 可以自适应,也可以换行,就是在最后一行的时候没有办法做到和前面的样式保持一致。像这样:
以及这样:
这样的布局显然不好看,同时也不规范。
查看了网上一些大神的文章,没有发现比较符合要求的解决方案。多数的解决方案都是基于静态的情况,比如拜读到比较多的一般会采用 css 的解决方案,在外框的 class 里加一个 ::after 来解决:
.ButtonGroup {
padding: 10px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.ButtonGroup::after {
content: ''
flex: auto;
}
亲测静态的情况下是可以解决问题的,但窗口宽度发生变化时,就不行了。
后面借鉴了一下 gird 的布局方式,利用 flex 充满的特性,使用了一点点 js,通过动态补齐的方式解决了这个问题。用 Vue3 做的,代码如下:
<div class = "ButtonGroup" id = "ButtonGroup">
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div class = "ButtonGroupItem ButtonTemplate"></div>
<div v-for = "index in controlInfo.buttonGroup.supplementIndex" :key = "index" class = "ButtonTemplate"></div>
</div>
.ButtonGroup {
padding: 10px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.ButtonGroupItem {
background: #100;
}
.ButtonTemplate {
height: 100px;
width: 180px;
margin: 5px;
flex-grow: 1;
}
export default {
data () {
return {
controlInfo: {
buttonGroup: {
supplementIndex: 0
}
}
}
},
methods: {
WindowOnresize: function () {
const buttonGroupObj = document.getElementById('ButtonGroup')
const buttonGroupWidth = buttonGroupObj.getBoundingClientRect().width
const buttonGroupItemList = document.getElementsByClassName('ButtonGroupItem')
const buttonGroupItemCount = buttonGroupItemList.length
const unitButtonWidth = buttonGroupItemList[0].getBoundingClientRect().width
const rowButtonCount = parseInt(buttonGroupWidth / unitButtonWidth)
this.controlInfo.buttonGroup = {
supplementIndex: rowButtonCount - buttonGroupItemCount % rowButtonCount
}
}
},
mounted () {
var _this = this
window.onresize = function () {
_this.WindowOnresize()
}
_this.WindowOnresize()
}
}
这样后期如果需要新增一个区域,就可以直接在 html 上增加,而不需要修改任何样式和 js。就算是要修改区域大小,也只要在 css 里修改一次即可。符合 Yogurt 这种 “懒癌患者” 的维护需求。
以防万一,特此笔记