在小程序中使用view、text模拟tr、td,实现table表的绘制与展示。优点是可扩展性强,缺点是无法像富文本一样还原样式。

效果


思路

  1. 首先选使用什么标签模拟表格,因为没有涉及复杂显示,这里使用基础的<view>。其他如cover-view,再根据需要自行扩展。
  2. 标签决定好,css布局样式要使用什么来绘制?考虑过后本示例使用flex布局,按照每一行来顺序渲染。
  3. 标签、布局确定好,思考如果通过for循环绘制标签,这里可以先反推,表格的数据如何构建。
  4. 先确定一个大致的绘制思路。如下json(假的)

    {
     "content1": {
         "tr": {
             "td": [
                 {
                     "type": "content",
                     "content": "123"
                 }
             ],
             "td": [
                 {
                     "type": "content",
                     "content": "312"
                 }
             ]
         },
         "tr": {
             "td": [
                 {
                     "type": "content",
                     "content": "123"
                 }
             ],
             "td": [
                 {
                     "type": "content",
                     "content": "312"
                 }
             ]
         }
     }
    }
  5. 按照行来拆分,每一行是tr,tr中每一列是td,td中可以再继续差分为内容数组。
  6. 有了基础数据,思考合并单元格时如何处理?
  7. 参照原始html的table合并单元格,同样使用rowspan\`colspan实现。使用例如colspan:3`对数据标识。
  8. 现在重新整理一下数据结构,得到如下结果。

    {
                     type: 'table',
                     node: [{
                             "id": "1322",
                             "type": "tr",
                             "node": [{
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": ""
                                     }]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "劳动合同"
                                     }]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "劳务派遣协议"
                                     }]
                                 }
                             ]
                         },
                         {
                             "id": "1323",
                             "type": "tr",
                             "node": [{
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "1.签订主体"
                                     }]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "劳务派遣单位与被派遣劳动者"
                                     }]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "劳务派遣单位与被派遣劳动者"
                                     }]
                                 }
                             ]
                         },
                         {
                             "id": "1324",
                             "type": "tr",
                             "node": [{
                                     "type": "td",
                                     "rowspan": 3,
                                     "node": [{
                                         "type": "content",
                                         "content": "2.其他规定"
                                     }]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                             "type": "content",
                                             "content": "(1)"
                                         },
                                         {
                                             "id": "2001",
                                             "type": "answer",
                                             "content": "______"
                                         },
                                         {
                                             "type": "content",
                                             "content": "的固定期限劳动合同,按月支付劳动报酬"
                                         }
                                     ]
                                 },
                                 {
                                     "type": "td",
                                     "node": [{
                                         "type": "content",
                                         "content": "劳务派遣单位应当将劳务派遣协议的内容告知被派遣劳动者"
                                     }]
                                 }
                             ]
                         },
                         {
                             "id": "1325",
                             "type": "tr",
                             "node": [{
                                 "type": "td",
                                 "node": [{
                                     "type": "content",
                                     "content": ""
                                 }]
                             }, {
                                 "type": "td",
                                 "colspan": 2,
                                 "node": [{
                                     "type": "content",
                                     "content": "(2)被派遣劳动者在无工作期间,劳务派遣单位应当按照所在地人民政府规定的最低工资标准,向其按月支付报酬"
                                 }]
                             }]
                         },
                         {
                             "id": "1326",
                             "type": "tr",
                             "node": [{
                                 "type": "td",
                                 "node": [{
                                     "type": "content",
                                     "content": ""
                                 }]
                             }, {
                                 "type": "td",
                                 "colspan": 2,
                                 "node": [{
                                     "type": "content",
                                     "content": "(3)劳务派遣单位和用工单位不得向被派遣劳动者收取费用"
                                 }]
                             }]
                         }
                     ]
                 
    }
  9. 到这思路大致梳理清晰,尝试写代码实现一下效果。

实现

  • 如下代码是在uniapp中编写,为方便运行到微信小程序、抖音小程序。其他端的代码思路大致相同。
  • 代码v-for中key注意更改

源码

<template>
    <view class="table-body">
        <!-- tr 层 -->
        <view class="table-tr" v-for="tr in content.node" :key="tr.id">
            <!-- td 层 -->
            <view class="table-td" :style="[...tableTdStyle(td)]" v-for="(td, index) in tr.node" :key="index">
                <!-- td 内容层 -->
                <view :style="[...tableTdContentStyle(td)]">
                    <text class="table-content-text" v-for="(tdNode, index2) in td.node" :key="index2">
                        {{ tdNode.content }}
                    </text>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    // table td的最小长度 rpx
    const minWidth = 450
    // table td的最小高度 rpx
    const minHeight = 100

    export default {
        name: 'ExercisesTable',
        data() {
            return {
                content: {
                    type: 'table',
                    node: [{
                            "id": "1322",
                            "type": "tr",
                            "node": [{
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": ""
                                    }]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "劳动合同"
                                    }]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "劳务派遣协议"
                                    }]
                                }
                            ]
                        },
                        {
                            "id": "1323",
                            "type": "tr",
                            "node": [{
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "1.签订主体"
                                    }]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "劳务派遣单位与被派遣劳动者"
                                    }]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "劳务派遣单位与被派遣劳动者"
                                    }]
                                }
                            ]
                        },
                        {
                            "id": "1324",
                            "type": "tr",
                            "node": [{
                                    "type": "td",
                                    "rowspan": 3,
                                    "node": [{
                                        "type": "content",
                                        "content": "2.其他规定"
                                    }]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                            "type": "content",
                                            "content": "(1)"
                                        },
                                        {
                                            "id": "2001",
                                            "type": "answer",
                                            "content": "______"
                                        },
                                        {
                                            "type": "content",
                                            "content": "的固定期限劳动合同,按月支付劳动报酬"
                                        }
                                    ]
                                },
                                {
                                    "type": "td",
                                    "node": [{
                                        "type": "content",
                                        "content": "劳务派遣单位应当将劳务派遣协议的内容告知被派遣劳动者"
                                    }]
                                }
                            ]
                        },
                        {
                            "id": "1325",
                            "type": "tr",
                            "node": [{
                                "type": "td",
                                "node": [{
                                    "type": "content",
                                    "content": ""
                                }]
                            }, {
                                "type": "td",
                                "colspan": 2,
                                "node": [{
                                    "type": "content",
                                    "content": "(2)被派遣劳动者在无工作期间,劳务派遣单位应当按照所在地人民政府规定的最低工资标准,向其按月支付报酬"
                                }]
                            }]
                        },
                        {
                            "id": "1326",
                            "type": "tr",
                            "node": [{
                                "type": "td",
                                "node": [{
                                    "type": "content",
                                    "content": ""
                                }]
                            }, {
                                "type": "td",
                                "colspan": 2,
                                "node": [{
                                    "type": "content",
                                    "content": "(3)劳务派遣单位和用工单位不得向被派遣劳动者收取费用"
                                }]
                            }]
                        }
                    ]
                }
            }
        },
        computed: {
            /* 
            td 自定义样式 
             */
            tableTdStyle() {
                return (item) => {
                    const {
                        rowspan,
                        colspan,
                        node
                    } = item
                    let w = minWidth
                    let h = minHeight

                    let style = []

                    // 如果有colspan 模拟横向合并单元格
                    if (colspan) {
                        w = colspan * minWidth
                    }

                    // 默认给所有td限制最小宽和最小高
                    style = [{
                        "width": `${w}rpx`,
                        "height": `${h}rpx`
                    }]

                    // 默认给所有td添加左右边框
                    style.push({
                        "border-left": "1px solid",
                        // "border-right": "1px solid"
                    })

                    // 如果子级有内容,不是空白占位,
                    // 且 没有竖向合并单元格
                    // 添加上下border
                    if (node[0].content && !rowspan) {
                        style.push({
                            "border-top": "1px solid",
                            "border-bottom": "1px solid"
                        })
                    }

                    return style
                }
            },
            /* 
             td 内容自定义样式
             */
            tableTdContentStyle() {
                return (item) => {
                    const {
                        rowspan,
                        node
                    } = item
                    let w = minWidth
                    let h = minHeight
                    let style = []
                    if (rowspan) {
                        h = rowspan * minHeight
                        style = [{
                                "height": `${h}rpx`
                            },
                            {
                                "position": "absolute",
                                // bfc
                                "overflow": "hidden",
                                "resize": "both"
                            },
                            {
                                "display": "flex"
                            },
                            {
                                "top": 0
                            },
                            {
                                "justify-content": "center"
                            },
                            {
                                "align-items": "center"
                            },
                        ]
                    }

                    return style
                }
            }
        }
    }
</script>

<style lang="scss" scoped>
    .table-body {
        display: inline-flex;
        flex-direction: column;
        border: 1px solid;
    }

    .table-tr {
        display: inline-flex;
        flex-direction: row;
        align-items: center;
    }

    .table-td {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        position: relative;
        // 修复border重叠问题
        margin: -1px 0px 0px -1px;
    }

    .table-content-text {
        font-size: 26rpx;
        letter-spacing: 2rpx;
    }
</style>
最后修改:2023 年 02 月 23 日
如果觉得我的文章对你有用,奖励一杯咖啡吧!