uni-app不使用table,手码一个有合并单元格的表格
(如果项目急的话直接复制代码,不急的话后面有思路可康康) 效果图 缺点的话就是高度是固定死的,这个感觉可以实现自适应(现在能用就行),暂时没有自适应就加个点击事件展示内容吧,在H5展示这些表格数据的确不太友好QAQ。
首先先把需要用到的数据挂出来 这个是表格的数据(虽然只是头部的数据,但是头部能合并了,内容自然也比较简单啦),说明下数据的字段分别是什么 树对象结构,然后td代表内容, tdRowspan代表行占多少个单元格(行合并), tdColspan代表列占多少个单元格(列合并)
packHeader: [
{
A: {
td: "支表支付证书",
tdRowspan: 1,
tdColspan: 10,
},
B: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
C: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
D: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
E: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
F: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
G: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
H: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
I: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
J: {
td: "",
tdRowspan: 0,
tdColspan: 0,
}
},
{
A: {
td: "清单号",
tdRowspan: 2,
tdColspan: 1,
},
B: {
td: "清单项目内容",
tdRowspan: 2,
tdColspan: 1,
},
C: {
td: "清单金额",
tdRowspan: 2,
tdColspan: 1,
},
D: {
td: "变更金额",
tdRowspan: 1,
tdColspan: 2,
},
E: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
F: {
td: "到本期末累计完成",
tdRowspan: 2,
tdColspan: 1,
},
G: {
td: "到上期末累计完成",
tdRowspan: 2,
tdColspan: 1,
},
H: {
td: "本期完成",
tdRowspan: 2,
tdColspan: 1,
},
I: {
td: "监理审核本期完成",
tdRowspan: 2,
tdColspan: 1,
},
J: {
td: "备注",
tdRowspan: 2,
tdColspan: 1,
}
},
{
A: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
B: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
C: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
D: {
td: "本期变更",
tdRowspan: 1,
tdColspan: 1,
},
E: {
td: "监理审核本期变更",
tdRowspan: 1,
tdColspan: 1,
},
F: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
G: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
H: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
I: {
td: "",
tdRowspan: 0,
tdColspan: 0,
},
J: {
td: "",
tdRowspan: 0,
tdColspan: 0,
}
},
{
A: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
B: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
C: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
D: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
E: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
F: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
G: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
H: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
I: {
td: "",
tdRowspan: 1,
tdColspan: 1,
},
J: {
td: "",
tdRowspan: 1,
tdColspan: 1,
}
}
],
HTML这块由于app没有dom这一东西所以样式需要一开始定好,判断会有点多
packHeader是上面的数据
letterHeadData是一个["A","B",....."F"] 的数组 等下在js生成
<scroll-view class="scrool-more" scroll-x="true" @scroll="scroll" scroll-left="0">
<view class="da-table" >
<view class="da-table-head" >
<view class="da-table-head-tr" v-for="(item, index) in packHeader" :key="index" >
<template v-for="(hitem, hindex) in letterHeadData" >
<view class="da-table-head-th" :key="hindex"
:style="(item[hitem].tdColspan && (item[hitem].tdColspan * 1 >= 1) ? 'width:' + item[hitem].tdColspan * 200 + 'px!important;' : 'display:none!important;') + (item[hitem].tdRowspan ? 'height:' + (item[hitem].tdRowspan ) * 40 + 'px!important;' : '') + (item[hitem].tdFloat ? 'position:absolute!important;background:white;z-index:999;' : '')">
<text class="da-thead-th-text" > {{ item[hitem].td }} </text>
</view>
<!-- 加这个是让哪些格子帮浮动的格子占位置 -->
<view :key="hindex + 'float'" v-if="item[hitem].tdFloat "
:style="(item[hitem].tdColspan ? 'width:' + item[hitem].tdColspan * 200 + 'px!important;display: inline-block!important;visibility: hidden;' : 'display: inline-block!important;') ">
<text>看我</text>
</view>
</template>
</view>
</view>
</view>
</scroll-view>
接下来是生成letterHeadData 的 JS
。
// 获取头部字母表头
getlitterTableHead() {
let azData = this.AZsort()
let tableLength = Object.keys(this.packHeader[0]).length
this.letterHeadData = azData.splice(0, tableLength) // 这个记得声明哦
console.log(this.letterHeadData, tableLength, 'dadada', this.packHeader[0])
},
// 生成数组的
AZsort() {
let arr = [];
for (let i = 0; i < 26; i++) {
arr.push(String.fromCharCode((65 + i)))
// console.log(String.fromCharCode((65 + i)))
// console.log(i)
}
for (let j = 0; j < 26; j++) {
for (let c = 0; c < 26; c++) {
arr.push(arr[j] + arr[c])
// console.log(arr[j]+String.fromCharCode((65 + c)))
}
}
return arr;
},
下面展示一些 内联代码片
。
generateMergeTable() {
let tableLength = this.packHeader.length // 表格有多少行
for (let i = 0; i < tableLength; i++) {
let keyData = this.packHeader[i] // 获取这一行的数据
// 遍历判断出占两行的单元格让其脱离文档流
Object.keys(keyData).forEach(key =>{
console.log(keyData[key].tdRowspan)
if (keyData[key].tdRowspan * 1 >= 2) {
keyData[key].tdFloat = true
if (i + 1 < tableLength) {
// 第几行
let firstTemp = this.packHeader[i + 1]
// 第几列
firstTemp[key].tdColspan = keyData[key].tdColspan * 1
}
}
})
}
然后就是样式方面的处理了 这个真的比较麻烦点 css
。
.da-table{
display: inline-table;
padding:10px;
transform: scale(0.7);
transform-origin: 0 0;
margin-bottom: 20px;
}
.da-table-head{
position: relative;
border-left: 1px solid #5d5d5d;
border-bottom: 1px solid #5d5d5d;
}
.da-table-head-tr{
position: relative;
min-height: 40px;
display: block;
}
.da-table-head-th{
border-right:1px solid #5d5d5d;
border-top: 1px solid #5d5d5d;
position: relative;
display: inline-block;
word-break: normal!important;
text-align: center;
padding-left: 10upx;
vertical-align: top;
line-height: 40px;
height: 40px;
overflow: hidden;
}
.da-table-body {
border: 1px solid #5d5d5d;
border-top: 0px;
border-right: 0px;
}
.da-thead-th-text{
white-space: normal;
word-break: break-all;
font-size:16px;
overflow: hidden;
position: absolute;
top: 48%; /*偏移,居中*/
left: 0;
right: 0;
transform: translateY(-50%)!important;
line-height: 17px;
}
.scrool-more{
white-space: nowrap;
width: 100%;
display: inline-block;
}
思路
最简单的表格肯定没有合并一行一个一个排过去啦 v-for="(item, index) in packHeader" v-for="(hitem, hindex) in letterHeadData" 所以通过循环各自获取键值,遍历出来, 然后就是合并列的,我就想合并列就是把右边的位置占了,宽度变成原来的几倍几倍就行了,刚好我们的数据中没有占位置的tdColspan为0,有位置的就大于0,那有位置的宽度就是,tdColspan * (你想要点宽度)。0 * tdColspan虽然是0,但是又边框在,所以就设置 display:none; 不让其显示就可以啦,(●ˇ∀ˇ●)
合并列的话,有好多要考虑,一个就是你高度改变,旁边单元格没有改变,会造成高度不一致,像这样子
这时候我就用position:absolute; 高度不会受影响了,但是因为脱离了文档流,使得后面的单元格往左边顶了
然后就很难受,- -,想了想,要不在浮动元素的底下在加一个假块 占占位置,结果还真可以,绝了。
下面展示一些 内联代码片
。
这也就是写这段代码的原因
<view :key="hindex + 'float'" v-if="item[hitem].tdFloat "
:style="(item[hitem].tdColspan ? 'width:' + item[hitem].tdColspan * 200 + 'px!important;display: inline-block!important;visibility: hidden;' : 'display: inline-block!important;') ">
<text>看我</text>
</view>
在 generateMergeTable() 进行数据处理
这里
// 遍历判断出占两行的单元格让其脱离文档流
Object.keys(keyData).forEach(key =>{
console.log(keyData[key].tdRowspan)
if (keyData[key].tdRowspan * 1 >= 2) {
keyData[key].tdFloat = true
之后又发现下一行的也往左边移动了
原因是因为上面合并,下面这一个的行列占位就变成0了,这时候还是用占位的方法,
下面展示一些 内联代码片
。
这个也是generateMergeTable()里面的数据处理,将下一行同个键里面的tdColspan进行处理就可以啦
if (i + 1 < tableLength) {
// 第几行
let firstTemp = this.packHeader[i + 1]
// 第几列
firstTemp[key].tdColspan = keyData[key].tdColspan * 1
}
原创内容,转载需标明来源。