前言
uni-app 插件市场 各类table插件挺多的,基本上我都下载试了个遍,最后各有各的不满意 还是自己撸了一个,自己也试了 好几种布局方式,做了好几款demo都不满意,只到改了一款 可以 左右列固定 根据tableHead批量遍历渲染数据 的table
最重要一点是 项目是 uni-app 打包成 ios或android -app项目,而该类项目 不支持 :class :style 动态样式绑定
一、思路
首先 功能需求是 根据tableHead可以批量渲染数据、 左右列(左侧序号列及扩展固定列,右侧 操作功能列)可以固定
本来先尝试做了几种 比如 tr内部分 左中右布局, 这样 左右行高可以随中部数据行高相同,但左右列 尝试各种css样式布局 都不成功,及 ios或android打包项目 不支持 :class :style 动态样式绑定 只好作罢
而后尝试 分三个table 方式制作成功
二、代码
1.布局
<!-- table -->
<view class="table-wrapper">
<view ref="table" class="my-table mb10">
<view class="left-table" v-if="isTableLeftFlag">
<thead class="table-head">
<tr>
<th class="table-left-float" v-if="isTableNumberSortFlag">
<view class="my-td-p w50">order</view>
</th>
</tr>
</thead>
<tbody class="table-body" v-if="tableList.length > 0">
<tr class="" v-for="(row,index) in tableList" :key="index">
<td class="table-left-float" v-if="isTableNumberSortFlag">
<view class="my-td-p w50">{{index+1}}</view>
</td>
</tr>
</tbody>
<tbody class="table-body" v-else>
<tr class="table-left-float" colspan="1">
<td colspan="1">
<view class="my-td-p">
1
</view>
</td>
</tr>
</tbody>
</view>
<view class="center-table">
<thead class="table-head">
<tr>
<th class="table-center-float" v-for="(header,index) in tableHead" :key="index">
<view class="my-td-p " v-if='header.key ==="id"'>{{header.title}}</view>
<view class="my-td-p " v-else-if='header.key === "operator"'>{{header.title}}</view>
<view class="my-td-p " v-else-if='header.key === "modifyTime"'>{{header.title}}</view>
<view class="my-td-p " v-else>{{header.title}}</view>
</th>
</tr>
</thead>
<tbody class="table-body" v-if="tableList.length > 0">
<tr class="table-content" v-for="(row,index) in tableList" :key="index">
<td class="table-center-float" v-for="(item3,index3) in tableHead" :key="index3">
<view class="my-td-p " v-if='item3.key ==="id"'>{{row[item3.key]}}</view>
<view class="my-td-p " v-else-if='item3.key === "operator"'>{{row[item3.key]}}</view>
<view class="my-td-p " v-else-if='item3.key === "modifyTime"'>{{row[item3.key]}}</view>
<view class="my-td-p " v-else>{{row[item3.key]}}</view>
</td>
</tr>
</tbody>
<tbody class="table-body" v-else>
<tr colspan="3">
<td colspan="3">
<view class="my-td-p">
No data available
</view>
</td>
</tr>
</tbody>
</view>
<view class="right-table" v-if="isTableRightFlag">
<thead class="table-head">
<tr>
<th class="table-left-float">
<view class="my-td-p">operate</view>
</th>
</tr>
</thead>
<tbody class="table-body" v-if="tableList.length > 0">
<tr class="" v-for="(row,index) in tableList" :key="index">
<td class="table-right-float">
<view class="my-td-p w100">
<!-- <text @click="editBtn(row)" class="mr10 c-01a4f6">编辑</text> -->
<text @click="deleteBtn(row)" class="c-01a4f6">删除</text>
</view>
</td>
</tr>
</tbody>
<tbody class="table-body" v-else>
<tr colspan="1">
<td class="table-right-float" colspan="1">
<view class="my-td-p">
删除
</view>
</td>
</tr>
</tbody>
</view>
</view>
<!-- 分页 -->
</view>
2.js
指定 几个字段 固定在左列,这个功能有实现 但这偷个懒 就不放了,批量勾选项 也是;
<script>
const defaultTableHead = [
// { key: 'id', title: 'id', width: '160' },
{ key: 'parcelNo', title: 'parcelNo', width: '160' },
// { key: 'warehouseId', title: '仓库id', width: '160' },
{ key: 'status', title: 'status', width: '100' },
{ key: 'remark', title: 'remark', width: '100' },
{ key: 'operator', title: 'operator', width: '100' },
{ key: 'createTime', title: 'createTime', width: '200' },
{ key: 'modifyTime', title: 'modifyTime', width: '200' },
]
const MockTableList = [
{ operator: '客户1打好后爱上撒配合', id: '00001', remark: '3', status: '1',modifyTime: '2020-09-10 22:10:00',createTime: '2020-09-10 22:10:00',parcelNo:'01',warehouseId:'01'},
{ operator: '客户2间回到还是都定好i但是', id: '00002', remark: '9', status: '0',modifyTime: '2020-09-10 22:10:00',createTime: '2020-09-10 22:10:00',parcelNo:'01',warehouseId:'01'},
{ operator: '客户3', id: '00003', remark: '6', status: '1',modifyTime: '2020-09-10 22:10:00',createTime: '2020-09-10 22:10:00',parcelNo:'01',warehouseId:'01'},
{ operator: '客户4', id: '00004', remark: '6', status: '1',modifyTime: '2020-09-10 22:10:00',createTime: '2020-09-10 22:10:00',parcelNo:'01',warehouseId:'01'},
{ operator: '客户5', id: '00005', remark: '6', status: '1',modifyTime: '2020-09-10 22:10:00',createTime: '2020-09-10 22:10:00',parcelNo:'01',warehouseId:'01'},
];
export default {
data() {
// idKey: 'id', // list的唯一主键
tableHead: defaultTableHead,
tableList: MockTableList,
tableLoading: false,
// selectRow: [], // table选中数组
isTableNumberSortFlag: true,
isTableLeftFlag: true, // 默认开启左侧 序号 固定列
isTableRightFlag: true, // 默认开启右侧 操作 固定列
},
methods: {
deleteBtn(item,index) {
console.log('deleteBtn()-item', item);
const nowList = this.tableList
this.tableList = nowList.splice(index, 1)
// this.getList()
},
}
}
3.css
<!-- table- 三个左种右分table 时 样式 -->
<style scoped>
/* 去掉表格的重复边框 */
table::-webkit-scrollbar {
display: none;
}
th{overflow: hidden;}
td{overflow: hidden;}
.table-wrapper{
padding: 0 10rpx;
}
/* 表头 */
.table-head {
overflow: hidden;
text-align: center;
white-space: nowrap;
}
.table-body{
text-align: center;
overflow-x: scroll;
min-height: 600rpx;
/* height: 600rpx; */
overflow-y: scroll;
}
.table-content{
overflow-x: scroll;
min-height: 600rpx;
}
.my-table{
overflow-y: scroll;
border-collapse:collapse;
border-spacing:0;
position: relative;
text-align: center;
display: flex;
align-items: center;
justify-content: flex-start;
}
.left-table{
z-index: 3;
background-color: #fff;
position: relative;
float: left;
}
.center-table{
z-index: 1;
background-color: #fff;
position: relative;
float: left;
width: 100%;
overflow: scroll;
}
.right-table{
z-index: 3;
background-color: #fff;
position: relative;
float: left;
}
.table-left-float{
/* float: left; */
/* position: absolute;
left:6rpx; */
background-color: #fff;
border-left: 2rpx solid #dedede;
border-right: 2rpx solid #dedede;
z-index: 2;
}
.table-center-float{
border-left: 2rpx solid #dedede;
border-right: 2rpx solid #dedede;
}
.table-right-float{
/* float: right; */
/* position: absolute;
right:6rpx; */
background-color: #fff;
border-left: 2rpx solid #dedede;
border-right: 2rpx solid #dedede;
z-index: 2;
}
tr{
width: 100%;
/* border: 2rpx solid #dedede; */
border-top: 2rpx solid #dedede;
border-bottom: 2rpx solid #dedede;
}
.my-td-p{
white-space: nowrap; /* 重点控制 字符不能换行,不然样式飞了 */
text-align: center;
/* height: 80rpx; */
display: inline-block;
line-height: 40rpx;
padding: 4rpx 4rpx;
margin: auto 0;
vertical-align: middle;
overflow: hidden;
min-width: 100rpx;
/* white-space:normal; */
}
</style>
<!-- 本页面用到个人 common公共样式 -->
<style scoped>
.mb5{margin-bottom: 10rpx;}
.mb10{margin-bottom: 20rpx;}
.w50{width: 100rpx;}
.w100{width: 200rpx;}
.c-01a4f6{color:#01a4f6 ;}
</style>