feat(cf-table): 新增表格组件

新增 cf-table 组件,包含以下功能:
- 支持数据展示和列配置
- 提供表头和表体插槽功能
- 支持最大高度设置
- 实现粘性表头效果
- 提供空数据展示
- 包含完整的组件结构和样式
This commit is contained in:
zhengw
2026-01-09 13:59:05 +08:00
parent 8a3d3ac60e
commit 779ea81406
4 changed files with 157 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
{
"component": true,
"styleIsolation": "shared",
"usingComponents": {}
}

View File

@@ -0,0 +1,39 @@
Component({
options: { addGlobalClass: true, multipleSlots: true },
/**
* 组件的属性列表
*/
properties: {
data: {
type: Array,
value: [],
},
columns: {
type: Array,
value: [],
},
maxHeight: {
type: String,
value: "auto",
},
useTheadSlot: {
type: Boolean,
value: false,
},
useTbodySlot: {
type: Boolean,
value: false,
},
},
/**
* 组件的初始数据
*/
data: {},
/**
* 组件的方法列表
*/
methods: {},
});

View File

@@ -0,0 +1,41 @@
<view class="table-box" style="max-height:{{maxHeight}}">
<view class="table table-sticky">
<view class="table-column-group">
<block wx:for="{{columns}}" wx:key="index">
<view class="col" style="width: {{item.width}}" />
</block>
</view>
<view class="tr">
<block wx:if="{{useTheadSlot}}">
<slot name="thead" />
</block>
<block wx:else>
<block wx:for="{{columns}}" wx:key="index">
<view class="th">{{item.title}}</view>
</block>
</block>
</view>
</view>
<view class="table table-content">
<view class="table-column-group">
<block wx:for="{{columns}}" wx:key="index">
<view class="col" style="width: {{item.width}}" />
</block>
</view>
<block wx:if="{{useTbodySlot}}">
<slot name="tbody" />
</block>
<block wx:else>
<view wx:if="{{data.length == 0}}" class="tr" style="height: 32px" />
<block wx:for="{{data}}" wx:key="index" wx:for-item="record">
<view class="tr">
<block wx:for="{{columns}}" wx:key="index">
<view class="td">{{record[item.dataIndex]}}</view>
</block>
</view>
</block>
</block>
</view>
</view>
<view wx:if="{{!useTbodySlot && data.length == 0}}" class="empty-data">暂无数据</view>

View File

@@ -0,0 +1,71 @@
.table-box {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
overflow: auto;
}
.table {
display: table;
table-layout: fixed;
box-sizing: border-box;
width: 100%;
}
.table-column-group {
display: table-column-group;
}
.col {
display: table-column;
}
.thead {
position: sticky;
top: 0;
z-index: 1;
background: #f5f5f5;
}
.tr {
display: table-row;
}
.th {
background-color: #f5f5f5;
}
.th,
.td {
display: table-cell;
border-bottom: 1px solid #ddd;
padding: 4px;
border-right: 1px solid #ddd;
vertical-align: middle;
}
.tr .th {
border-top: 1px solid #ddd;
}
.tr .th:last-child,
.tr .td:last-child {
border-right: none;
}
.table-sticky {
position: sticky;
top: 0;
z-index: 1;
}
.table-content .tr:last-child .td {
border-bottom: none;
}
.empty-data {
text-align: center;
margin-top: -33px;
line-height: 30px;
color: #999;
}