很简单的一个表格展示,自己写的,功能一般般。
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>

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