小程序跨行跨列多列复杂表格实现
今天来实现个跨行跨列多列表格。
如图,这是个列数不确定,有的单元格还要跨行跨列的复杂表格。
这里暂时最多支持4列,列数再多就放不下了。
实现原理
实现原理比较简单,通过多个嵌套的循环将数据取出。
上面的例子中,最外层一共有4行:基础工资,加班工资,岗位工资,合计。第一层数据的 name
展示为第一列,如果每组数据有 children
,取出 children
展示为第二列… 如果 children
长度为0,则直接显示工资数额。
这样一层一层把数据剖开,就做到了上面的效果。
数据格式
模拟的数据如下,如果是最后一层 value
值为工资数额,否则值为 null
。嵌套的数据在 children
中
-
// 模拟的数据
-
export default {
-
status: 200,
-
code: "ok",
-
data: [{
-
id: 'table001',
-
name: '基础工资',
-
value: null,
-
children: [{
-
id: 'table0011',
-
name: '基本工资',
-
value: 3000.0,
-
children: []
-
},
-
{
-
id: 'table0012',
-
name: '绩效工资',
-
value: 1200.0,
-
children: []
-
},
-
{
-
id: 'table0013',
-
name: '基本工作量',
-
value: null,
-
children: [{
-
id: 'table00131',
-
name: '课时工资',
-
value: 800.0,
-
children: []
-
},
-
{
-
id: 'table00132',
-
name: '超课时工资',
-
value: 200.0,
-
children: []
-
},
-
]
-
},
-
]
-
},
-
{
-
id: 'table002',
-
name: '加班工资',
-
value: null,
-
children: [{
-
id: 'table0021',
-
name: '工作日加班',
-
value: 1000.0,
-
children: []
-
},
-
{
-
id: 'table0022',
-
name: '周末加班',
-
value: 600.0,
-
children: []
-
},
-
]
-
},
-
{
-
id: 'table003',
-
name: '岗位工资',
-
value: 1800.0,
-
children: [
-
]
-
},
-
{
-
id: 'table004',
-
name: '合计',
-
value: 8600.0,
-
children: []
-
},
-
]
-
}
-
复制代码
页面布局
wxml文件
-
<view class='container'>
-
<picker class='picker' mode='date' fields='month' bindchange='dateChange'>
-
<view class='picker-content'>
-
<image class='date-icon' src='../../assets/date_48.png'></image>
-
<view class='date-text'>{{currentDate}}</view>
-
</view>
-
</picker>
-
<view class='title-wrapper'>
-
<text class='title'>{{username + " 老师 " + currentDate + " 月工资表"}}</text>
-
<text class='yuan'>单位:元</text>
-
</view>
-
<view class='table-wrapper'>
-
<view class='nodata' wx:if='{{list.length === 0}}'>本月暂无工资数据</view>
-
<view class='row1' wx:if='{{list.length > 0}}' wx:for='{{list}}' wx:key='{{item.id}}'>
-
<text class='text'>{{item.name}}</text>
-
<view class='column2-wrapper'>
-
<view class='column-value' wx:if='{{item.value}}'>{{item.value}}</view>
-
<view class='column2' wx:if='{{item.children.length > 0}}' wx:for='{{item.children}}' wx:for-item='item2' wx:key='{{item2.id}}'>
-
<text class='text'>{{item2.name}}</text>
-
<view class='column3-wrapper'>
-
<view class='column-value' wx:if='{{item2.value}}'>{{item2.value}}</view>
-
<view class='column3' wx:if='{{item2.children.length > 0}}' wx:for='{{item2.children}}' wx:for-item='item3' wx:key='{{item3.id}}'>
-
<text class='text'>{{item3.name}}</text>
-
<view class='column4-wrapper'>
-
<view class='column-value' wx:if='{{item3.value}}'>{{item3.value}}</view>
-
</view>
-
</view>
-
</view>
-
</view>
-
</view>
-
</view>
-
</view>
-
</view>
-
复制代码
wxss 文件
-
.container {
-
width: 100%;
-
display: flex;
-
flex-direction: column;
-
box-sizing: border-box;
-
background: white;
-
}
-
.picker {
-
width: 100%;
-
}
-
.date-text {
-
font-size: 32rpx;
-
padding: 20rpx 10rpx;
-
text-align: center;
-
}
-
.title-wrapper {
-
display: flex;
-
width: 100%;
-
justify-content: center;
-
align-items: center;
-
padding: 20rpx;
-
box-sizing: border-box;
-
}
-
.title {
-
flex: 1;
-
font-size: 34rpx;
-
text-align: center;
-
font-weight: 700;
-
color: #09bb07;
-
}
-
.yuan {
-
font-size: 24rpx;
-
color: #09bb07;
-
}
-
.table-wrapper {
-
width: 100%;
-
display: flex;
-
flex-direction: column;
-
border-top: 1rpx solid #DCDFE6;
-
}
-
.row1 {
-
width: 100%;
-
display: flex;
-
flex-direction: row;
-
align-items: center;
-
font-size: 32rpx;
-
box-sizing: border-box;
-
border-bottom: 1rpx solid #DCDFE6;
-
}
-
.text {
-
flex: 1;
-
padding: 10rpx;
-
line-height: 60rpx;
-
height: 60rpx;
-
}
-
.column2-wrapper {
-
display: flex;
-
flex-direction: column;
-
flex: 3;
-
justify-content: center;
-
border-left: 1rpx solid #DCDFE6;
-
}
-
.column2 {
-
display: flex;
-
flex: 1;
-
align-items: center;
-
border-bottom: 1rpx solid #DCDFE6;
-
}
-
.column2:last-child{
-
border-bottom: none;
-
}
-
.column3-wrapper {
-
display: flex;
-
flex-direction: column;
-
flex: 2;
-
justify-content: center;
-
border-left: 1rpx solid #DCDFE6;
-
}
-
.column3 {
-
display: flex;
-
flex: 1;
-
align-items: center;
-
border-bottom: 1rpx solid #DCDFE6;
-
}
-
.column3:last-child{
-
border-bottom: none;
-
}
-
.column-value{
-
display: flex;
-
align-self: flex-end;
-
margin-right: 10rpx;
-
padding: 10rpx;
-
line-height: 60rpx;
-
height: 60rpx;
-
}
-
.column4-wrapper{
-
display: flex;
-
flex-direction: column;
-
flex: 1;
-
justify-content: center;
-
border-left: 1rpx solid #DCDFE6;
-
}
-
.picker-content{
-
display: flex;
-
width: 100%;
-
justify-content: center;
-
align-items: center;
-
border-bottom: 1rpx solid rgba(7, 17, 27, 0.1);
-
}
-
.date-icon{
-
width: 80rpx;
-
height: 80rpx;
-
}
-
.nodata{
-
width: 100%;
-
text-align: center;
-
font-size: 32rpx;
-
color: #666;
-
padding: 20rpx;
-
}
-
复制代码
js 文件
-
import MockData from './mockdata.js'
-
import {
-
formatTime
-
} from '../../utils/util.js'
-
Page({
-
data: {
-
currentDate: '',
-
username: '张三',
-
list: ''
-
},
-
onLoad: function () {
-
wx.setNavigationBarTitle({
-
title: '工资查询',
-
})
-
//设置当前年月
-
this.setCurrentDate()
-
this._getSalary()
-
},
-
setCurrentDate(){
-
//获取当前年月
-
let date = new Date()
-
let fmtDate = formatTime(date).substring(0, 7)
-
this.setData({
-
currentDate: fmtDate,
-
})
-
console.log(fmtDate)
-
},
-
//日期变化回调
-
dateChange(res) {
-
console.log(res)
-
let value = res.detail.value
-
this.setData({
-
currentDate: value
-
})
-
//请求数据
-
this._getSalary()
-
},
-
//模拟请求数据
-
_getSalary(){
-
this.setData({
-
list: MockData.data
-
})
-
}
-
})
-
复制代码
逻辑很简单,主要是布局稍微复杂些,理清楚了也挺好理解。
源码地址: https://github.com/cachecats/wechat-table