对
uni-table
的封装
优点:自带样式,自带多选等功能
缺点:
1. 不能对checkbox
的value
进行赋值,选出来的选中行的index
2.checkbox
不能设置默认禁用
3.checkbox
不能获取到当前行数据,只能在改变选择状态时获取全部选中行
<template>
<view class="x-table-box" :style="{height:height}">
<uni-table @selection-change="chkchange" ref="table" :type="chk?'selection':''" class="x-table" stripe emptyText="暂无更多数据">
<uni-tr class="thead">
<uni-th
v-if="cols"
v-for="x,i in Object.keys(cols)"
:width="cols[x].width||120"
:class="{left0:!chk&&i==0,left5:chk&&i==0}"
>{{cols[x].title || x}}uni-th>
<uni-th v-if="btns" :width="btnswidth">操作uni-th>
uni-tr>
<uni-tr v-for="x in list" :style="trstyle(x)">
<uni-td
v-if="cols"
v-for="c,i in Object.keys(cols)"
:width="cols[c].width||120"
:class="{left0:!chk&&i==0,left5:chk&&i==0}"
v-html="fmt(cols[c].fmt,x[c],x)"
:style="trstyle(x)"
>uni-td>
<uni-td :style="trstyle(x)" class="x-table-btns" v-if="btns" :width="btnswidth">
<button @click="b.click(x)" :disabled="b.disabled?b.disabled(x):false" :class="b.class" :type="b.type" v-for="b in btns">{{b.text}}button>
uni-td>
uni-tr>
uni-table>
<view class="uni-pagination-box"><uni-pagination show-icon :page-size="pagesize" :current="pageindex" :total="count" @change="fpage" />view>
view>
template>
export default {
name: "x-table",
props: {
/**
* 数据列表
* */
list: {
type: Array,
default: []
},
/**
* 是否开启多选
* 默认否
* */
chk: {
type: Boolean,
default: false
},
/**
* 列定义
* */
cols:{
type:Object,
default:null
},
/**
* 按钮列宽度
* */
btnswidth:{
type:Number,
default:100
},
/**
* 按钮列表
* 请根据按钮数量设置 按钮列宽度
* */
btns:{
type: Array,
default: []
},
/**
* 行样式
* 可以设置背景色或文字颜色来标记不同的数据状态
* */
trstyle:{
type:Function,
default:function(){}
},
/**
* 多选选择时触发
* */
chkchange:{
type:Function,
default:function(){}
},
/**
* 设置表格高度 css
* */
height:{
type:String,
default:'800px'
},
/**
* 每页长度
* */
pagesize:{
type:Number,
default:20
},
/**
* 起始页
* */
pageindex:{
type:Number,
default:1
},
/**
* 查询数据总量
* */
count:{
type:Number,
default:0
},
/**
* 翻页事件
* */
topage:{
type:Function,
default:function(){}
},
/**
* 选中行索引
* 每一页重新设置一次
* */
chkrow:{
type:Array,
default:[]
}
},
data() {
return {
};
},
watch:{
list(r){
this.selrow();
}
},
methods:{
/**
* 设置默认选中行
* */
selrow(){
this.$nextTick(()=>{
this.$refs.table.toggleRowSelection(this.chkrow,true);
})
},
/**
* 翻页事件
* current=翻页后的页码
* */
fpage(e){
console.log(e)
this.topage(e.current);
this.selrow();
},
/**
* 单元格数据格式化
* */
fmt(f,v,r){
if(f){
return f(v,r);
}
return v;
}
}
}
App.vue
里面才能生效
.x-table-btns button{
height: 24px;
line-height: 24px;
font-size: 14px;
display: inline-block;
margin-right: 2px;
}
.x-table-box {
width: 100%;
background-color: #fff;
height: 90%;
overflow: auto;
position: absolute;
}
.x-table{
border-collapse: collapse;
display: inline-block;
overflow: auto;
width: 100%;
position: absolute;
}
.uni-table-scroll{
height:calc(100% - 60px);
}
.uni-pagination-box{
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
padding: 15px;
box-sizing: border-box;
}
.x-table .thead {
position: sticky;
top: 0;
z-index: 9;
}
.x-table th,
.x-table td {
box-sizing: border-box;
background-color: #fff;
}
.x-table .checkbox {
position: sticky;
left: 0;
z-index: 8;
overflow: hidden;
}
.x-table .checkbox::before{
content: "";
position: absolute;
right: -1px;
top: -10px;
height: 200%;
width: 0.5px;
box-shadow:0px 0px 5px #000;
}
.x-table tr {
display: flex;
}
.x-table tr:hover,.x-table tr:hover td{
background-color:#eee;
}
@media (min-width:768px) {
.x-table-box {
max-width: calc(100vw - 200px) !important;
}
.x-table .left5 {
position: sticky;
left:36px;
border-right: 1px solid #eee;
overflow: hidden;
}
.x-table .left5::before{
content: "";
position: absolute;
right: -1px;
top: -10px;
height: 200%;
width: 0.5px;
box-shadow:0px 0px 5px #000;
}
}
@media (max-width:768px){
.x-table tbody{
display: inline-block;
width: 100%;
}
.x-table tr{
flex-direction: column;
background-color: #fff;
border-bottom: #ccc;
width: 100%;
margin-bottom: 10px;
}
.x-table .thead{
display: none;
}
.x-table th,
.x-table td {
border:none;
width: 100%;
}
.x-table-btns{
text-align: right;
}
.x-table-btns button{
height:30px;
line-height:30px;
font-size: 14px;
display: inline-block;
margin-right:10px;
}
}
position: sticky;
与上级元素position: absolute;
可做到冻结
名称 | 类型 | 描述 |
---|---|---|
list | Array | 数据列表 |
cols | Object | 列定义,详细信息见下面列定义 |
btns | Array | 按钮列表,请根据按钮数量设置—按钮列宽度,详细信息见下面按钮 |
btnswidth | Number | 按钮列宽度 |
chk | Boolean | 是否开启多选 默认否 |
height | String | 设置表格高度 css |
pagesize | Number | 每页长度 默认20 |
pageindex | Number | 起始页 默认1 |
count | Number | 查询数据总量 |
chkrow | Array | 选中行索引 [1,3,6] |
cols:{
//字段名
name:{
title:"姓名",//表头
width:100//列宽
},
//字段名
phone:{
title:"手机号",//表头
width:150,//列宽
/**
* 格式化数据
* */
fmt(v,r){
return '+86 '+r.phone;
}
},
}
btns:[
{
text:"编辑",//按钮文字
class:"btn1",//附加样式
type:"primary",//uniapp提供的按钮类型 蓝色primary/红色warn
//设置按钮状态,返回true按钮可用,false按钮不可用
disabled(r){
// r=当前行数据
return r.phone.indexOf('15')>-1;
},
//按钮单击事件
click(r){
// r=当前行数据
}
}
]
名称 | 类型 | 描述 |
---|---|---|
trstyle | Function | 行样式,可以设置背景色或文字颜色来标记不同的数据状态,详细信息见下面行样式 |
chkchange | Function | 选择事件,详细信息见下面选择事件 |
topage | Function | 翻页事件,详细信息见下面翻页事件 |
/**
* 判断数据状态,给行加上样式
**/
tablestyle(r){
// r=当前行数据
var style={
style.background="#ff9999";
};
if(r.phone>17000000000){
style.background="#ff66ff";
}
return style;
},
chkchange(v){
// v.detail.index 当前选中的所有行
console.log(v)
},
topage(e){
//e=当前页
this.pageindex=e;
//查询数据
this.getdata();
},
<x-table
:chkchange="chkchange"
:trstyle="tablestyle"
:btnswidth="200"
:btns="btns"
:list="table"
:cols="cols"
chk="true"
height="800px"
:key="phone"
:pagesize="pagesize"
:count="count"
chkchange="chkchange"
:topage="topage"
>x-table>