今天来实现个跨行跨列多列表格。
如图,这是个列数不确定,有的单元格还要跨行跨列的复杂表格。
这里暂时最多支持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