uniapp微信小程序简单表格展示

很简单的一个表格展示,自己写的,功能一般般。

javascript 复制代码
<template>
    <view class="x-simple-table" :style="{ width: width, height: height, maxHeight: maxHeight  }">
        <view class="x-simple-table-panel">
            <view class="table-header tui-flex-align-center">
                <view class="table-cell border-rb" v-for="header in effectiveHeaders" :key="header.onlyId"
                    :class="header.class"
                    :style="header.style">
                    {{ header.title }}
                </view>
            </view>
            <view v-for="cellOption in effectiveDataList" :key="cellOption.onlyId" class="table-row tui-flex-align-center">
                <view v-for="cell in cellOption.cellList" :key="cell.onlyId"
                    class="table-cell border-rb" :style="cell.style"
                     :class="cell.class">
                    {{ cell.value }}
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        props: {

            width: {
                type: String,
                default: 'auto'
            },

            height: {
                type: String,
                default: 'auto'
            },

            maxHeight: {
                type: String,
                default: 'auto'
            },
            
            headers: {
                type: Array,
                default: new Array()
            },

            dataList: {
                type: Array,
                default: new Array()
            }
        },

        data () {
            return {
                tableFieldWidth: 100,
                autoHeaderWidth: []
            }
        },

        computed: {

            effectiveHeaders () {
                let onlyId = Date.now()
                return this.headers.map((e, index) => {
                    const { field, width, hStyle = '', hClass = '' } = e
                    const { width: autoWidth } = this.autoHeaderWidth.find(ah => ah.field === field) || {}

                    const newHeader = { ...e, onlyId: onlyId++ * 2}

                    const styleArray = []
                    const classArray = [hClass]
                    // if (index < this.headers.length - 1) {
                    //     classArray.push('border-r')
                    // }
                    // if (this.dataList.length) {
                    //     classArray.push('border-b')
                    // }
                    if (width || autoWidth) {
                        newHeader.widthUnit = width ? 'rpx' : 'px'
                        styleArray.push(`width: ${width || autoWidth}${newHeader.widthUnit}`)
                    } else {
                        newHeader.autoWidthFlag = true
                        styleArray.push('flex: 1')
                        classArray.push(`x-auto-width-header-${field}`)
                    }
                    hStyle && styleArray.push(hStyle)
                    Object.assign(newHeader, {
                        width: width || autoWidth,
                        style: styleArray.join(';'),
                        class: classArray.join(' ')
                    })
                    return newHeader
                })
            },

            effectiveDataList () {
                if (!this.effectiveHeaders.length) {
                    return []
                }
                const nullValueArray = [void (0), null]
                const newDataList = []
                let onlyId = Date.now()
                for (let rowIndex = 0; rowIndex < this.dataList.length; rowIndex++) {
                    const row = this.dataList[rowIndex]
                    const tableCellValue = []
                    for (let cellIndex = 0; cellIndex < this.effectiveHeaders.length; cellIndex++) {
                        const header = this.effectiveHeaders[cellIndex]

                        const tClass = row[`${header.field}_class`]
                        const classArray = []
                        // if (cellIndex < this.effectiveHeaders.length - 1) {
                        //     classArray.push('border-r')
                        // }
                        // if (rowIndex < this.dataList.length - 1) {
                        //     classArray.push('border-b')
                        // }
                        tClass && classArray.push(tClass)

                        const tStyle = row[`${header.field}_style`]
                        const styleArray = [ `width: ${header.width || 0}${header.widthUnit || 'rpx'}` ]
                        tStyle && styleArray.push(tStyle)

                        const value = nullValueArray.includes(row[header.field]) ? '' : row[header.field] + (header.suffix || '')
                        tableCellValue.push({
                            $row: row,
                            style: styleArray.join(';'),
                            class: classArray.join(' '),
                            field: header.field,
                            value,
                            onlyId: onlyId++
                        })
                    }
                    newDataList.push({
                        onlyId: onlyId++,
                        cellList: tableCellValue
                    })
                }
                return newDataList
            }
        },

        mounted () {
            this.refactorCellWidth()
        },

        methods: {
            
            refactorCellWidth () {
                this.$nextTick(_ => {
                    const autoWidthHeaderList = this.effectiveHeaders.filter(e => e.autoWidthFlag)
                    if (!autoWidthHeaderList.length) {
                        return
                    }
                    const $el = uni.createSelectorQuery().in(this)
                    autoWidthHeaderList.forEach(header => {
                        $el.select(`.x-auto-width-header-${header.field}`)
                            .boundingClientRect(({ width }) => {
                                const ahRow = this.autoHeaderWidth.find(ah => ah.field === header.field)
                                if (ahRow) {
                                    ahRow.width !== width && this.$set(ahRow, 'width', width)
                                } else {
                                    this.autoHeaderWidth.push({
                                        field: header.field,
                                        width
                                    })
                                }
                            }).exec()
                    })
                })
            }
        }
    }
</script>
<style lang="scss" scoped>
    $border: 2rpx solid rgba(229, 229, 229, 1);
    .x-simple-table {
        border: $border;
        border-radius: 12rpx;
        font-size: 28rpx;
        color: rgba(102, 102, 102, 1);
        overflow: hidden;
        .x-simple-table-panel {
            overflow: auto;
        }
        .table-header, .table-row {
            align-items: stretch;
        }
        .table-cell {
            text-align: center;
            padding: 14rpx 8rpx;
            flex-shrink: 0;
            box-sizing: border-box;
            overflow: hidden;
            white-space: nowrap;
            min-width: 100rpx;
        }
        .border-r, .border-rb {
            border-right: $border;
        }
        .border-b, .border-rb {
            border-bottom: $border;
        }
    }
</style>


没什么单元格合并,但支持左右滑动,上下滑动,单元格自定义样式。


相关推荐
java1234_小锋6 小时前
【免费】基于Python的微信小程序网约车(打车,在线叫车,移动出行)系统(FastAPI+Vue3) 锋哥原创出品,必属精品
微信小程序·小程序·fastapi·网约车系统·在线叫车系统
满栀5858 小时前
vue动态路由效果
前端·javascript·vue.js·前端框架·vue
2501_9160074711 小时前
Bundle ID 注册与管理 App ID 创建指南 命名规则 权限开关与删除注意事项
android·ios·小程序·https·uni-app·iphone·webview
PedroQue9916 小时前
uni-app路由插件化:解锁高效开发新姿势
前端·uni-app
凡科网小帆16 小时前
2026小程序商城做的比较好的品牌,怎么选小程序商城品牌
小程序·小程序商城
碧水澜庭17 小时前
头条【vue+fastapi 】全栈教学项目系列之《02_双系统零基础环境搭建手册》
vue·fastapi
2501_9159090617 小时前
iOS 证书创建与管理 类型限制 p12 密码与云备份实操
android·ios·小程序·https·uni-app·iphone·webview
anyup18 小时前
【2026年8月】uView Pro 千星,还拿到了 GVP
前端·uni-app·github
andr_gale2 天前
02_uniapp自定义上凸效果的底部TabBar
前端·javascript·uni-app·移动端
拖孩2 天前
用 AI 重解千年观音灵签,做了一个微信小程序,每天摇一摇,命运给你回应
前端·后端·微信小程序