将表格转为Grid布局:如何自动匹配表头列数?
由于原生表格在移动端响应性差,我将所有表格转换为基于Grid的div结构,已实现如下代码结构:
<div class="table"> <div class="table-row"> <div class="table-header"> <span>Header</span> </div> <div class="table-header"> <span>Header</span> </div> <div class="table-header"> <span>Header</span> </div> </div> <div class="table-row"> <div class="table-cell" v-for="(type, column) in columns"> <span>Cell</span> </div> <div class="table-cell" v-for="(type, column) in columns"> <span>Cell</span> </div> <div class="table-cell" v-for="(type, column) in columns"> <span>Cell</span> </div> </div> <div class="table-row"> <div class="table-cell" v-for="(type, column) in columns"> <span>Cell</span> </div> <div class="table-cell" v-for="(type, column) in columns"> <span>Cell</span> </div> </div> </div> <style> .table { display: grid; } .table-row { display: contents; } .table-header, .table-cell {} .table-header {} </style>
该结构包含3行:第1行有3个表头,第2行有3个单元格,第3行有2个单元格。我尝试了grid-auto-flow、grid-auto-column、grid-auto-row、grid-template-columns等40余种属性组合,仍无法让Grid的列数n等于表头数量,请问是否只能通过JavaScript实现?
嘿,不用非得求助JavaScript哦!你遇到的问题其实是Grid布局的一个常见小坑——因为你给.table-row加了display: contents,这会让行里的表头和单元格直接变成.table这个Grid容器的直接子元素,默认情况下Grid不会自动识别表头的数量来设置列数,但我们有几个纯CSS或者利用Vue现有能力的解决办法:
1. 固定列数的情况(比如你现在的3个表头)
直接在CSS里给.table设置和表头数量一致的列数就行:
.table { display: grid; /* 3换成你的表头数量,1fr让列宽均分 */ grid-template-columns: repeat(3, 1fr); } .table-row { display: contents; }
这样不管后面的行有2个还是3个单元格,都会按照3列的布局排列,最后一行的2个单元格会占据前两列,第三列自动留空,完全符合你的需求。
2. 动态列数的情况(比如表头数量由Vue的columns数组控制)
既然你已经在用Vue了,直接利用模板的样式绑定就能动态设置列数,根本不用额外写JS逻辑:
<!-- 绑定grid-template-columns,用columns数组的长度定义列数 --> <div class="table" :style="{ gridTemplateColumns: `repeat(${columns.length}, 1fr)` }"> <div class="table-row"> <div class="table-header" v-for="(col, index) in columns" :key="index"> <span>{{ col }}</span> </div> </div> <!-- 其他行的代码... --> </div>
顺便提一句,你原来代码里的v-for写重复了,比如第二行的三个table-cell其实只需要一个v-for循环columns数组就行,不用写三次,这样代码更简洁也不容易出错。
3. 纯CSS动态方案(需现代浏览器支持)
如果你的项目不需要兼容旧浏览器,现在Chrome 117+、Firefox 118+已经支持CSS的count()函数了,我们可以直接用它来获取表头的数量:
.table { display: grid; /* 自动获取表头数量来设置列数 */ grid-template-columns: repeat(count(.table-header), 1fr); } .table-row { display: contents; }
这个方案完全不用依赖Vue或者JS,纯CSS就能搞定,但要注意浏览器兼容性哦。
总之,你有好几种不用额外JavaScript的解决办法,选最适合你项目情况的就行!
内容的提问来源于stack exchange,提问作者JTinkers

