增加注释 修改问题

This commit is contained in:
zouzhibing
2022-03-11 10:19:21 +08:00
parent 66eef50565
commit dd2d7b5c63
14 changed files with 1583 additions and 1878 deletions

View File

@@ -1,448 +0,0 @@
<template>
<!-- #ifdef H5 -->
<!-- #endif -->
<!-- #ifndef H5 -->
<view class="zb-table-applet">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;overflow: scroll">
<template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" >
<view class="item-tr">
<view
@click="sortAction(item,index)"
:class="['item-th',index === 0&&'zb-stick-side',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{
width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none',
minWidth:`${item.width?item.width:'100'}px`
}"
v-for="(item,index) in transColumns" :key="index">{{ item.label }}</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="!data.length">
<view class="no-data">暂无数据~~</view>
</template>
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
v-for="(item,index) in transData" :key="item.key" >
<view
:style="{
width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none',
minWidth:`${ite.width?ite.width:'100'}px`
}"
:class="['item-td',i === 0&&'zb-stick-side',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%">
<view
v-for="ren,ind in ite.renders"
:key="ind"
@click.stop="$emit(ren.func,item,index)"
:style="{
display:'flex',
alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0'
}">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view>
</view>
</template>
<template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- #endif -->
</template>
<script>
export default {
props:{
itemDate:{
type:Object,
default:()=>{}
},
rowKey:Function,
columns:{
type:Array,
default:()=>[]
},
data:{
type:Array,
default:()=>[]
},
showHeader:{
type:Boolean,
default:true
},
stripe:{
type:Boolean,
default:true
},
fit:{
type:Boolean,
default:false
},
},
computed:{
isFixedLeft(){
if(!this.columns.length){
return false
}
if(!this.data.length){
return false
}
let [firstArr] = this.columns
return !!firstArr.fixed;
},
transColumns(){
if(this.fit){
this.columns.forEach(column=>{
if(column.type==="operation"&&column.renders){
let str = column.renders.reduce((prev,next)=>{
return prev.name+next.name
})
column.width = this.getTextWidth(str)+column.renders.length*40
}else {
let arr = [this.getTextWidth(column.label)]
this.data.forEach(data=>{
let str = (data[column.name]+'')
let width = this.getTextWidth(str)
arr.push(width)
})
column.width = Math.max(...arr)+12
}
})
return this.columns
}
this.columns.forEach(item=>{
if(item.type==="operation"&&item.renders){
let str = item.renders.reduce((prev,next)=>{
return prev.name+next.name
})
item.width = this.getTextWidth(str)+item.renders.length*40
}
item.emptyString = item.emptyString||'--'
})
return this.columns
},
transData(){
this.data.forEach((item,index)=>{
if(this.rowKey){
item.key = Object.freeze(this.rowKey(item))
}else {
item.key = index
}
})
return this.data
}
},
data() {
return {
button:[],
bodyTableLeft:0,
headerTableLeft:0,
lastScrollLeft:0,
leftFiexScrollTop:0,
bodyScrollTop:0,
currentDriver:null,
currentDriver1:null,
bodyTime:null,
bodyTime1:null,
headerTime:null,
debounceTime:null,
operation:{},
completedFlag:false,
}
},
methods: {
itemFilter(item,ite){
if(ite.filters&&ite.name){
let key = item[ite.name]
return ite.filters[key]||''
}
return item[ite.name]||ite.emptyString
},
// 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
getTextWidth(str) {
let flexWidth = 0
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符为字符分配8个单位宽度
flexWidth += 8
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符为字符分配15个单位宽度
flexWidth += 18
} else {
// 其他种类字符为字符分配8个单位宽度
flexWidth += 8
}
}
return flexWidth
},
width(item){
return `${item.width?item.width:'100'}px`
},
showStripe(index){
if(this.currentDriver)return
if(this.stripe){
return (index % 2) != 0?'odd':'even'
}else{
return ''
}
},
//验证字符串是否是数字
checkNumber(theObj) {
var reg = /^[0-9]+.?[0-9]*$/;
if (reg.test(theObj)) {
return true;
}
return false;
},
isDate(data){
if(isNaN(data)&&!isNaN(Date.parse(data))){
return true
}
return false
},
sortAction(item,index){
this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
this.sortData(item)
},
sortData(item){
let key = item.name
if(item.sorterMode==='_asc'){
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return a[key]-b[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return a1-b1
}
})
}else {
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return b[key]-a[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return b1-a1
}
})
}
},
}
}
</script>
<style lang="scss">
.zb-table-fixed-left{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
.zb-table-header{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
</style>
<style lang="scss" scoped>
.no-data{
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e8e8e8;
}
.zb-table-applet{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
width: fit-content;
}
.sorting{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczRkE5Qjk2OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczRkE5Qjk3OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzNGQTlCOTQ5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzNGQTlCOTU5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4R7rKqAAAAWklEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFnI8RYIKCsrM5LkQlwaCMkxkeoKfIYRFYbIBhAybGjE8gg0ECDAAI+ULEsz8LFkAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_asc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlDMzQ5NTk4OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlDMzQ5NTk5OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OUMzNDk1OTY5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OUMzNDk1OTc5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4u6TUfAAAAdElEQVR42mL8//8/AzUBEwOVweA3kIVUDdJbp8LZT72zyXMh0JD/IIzLEJIMhBmEzMZnKCO+ZINsGDIAGshIsgtxGUZIjnHQJ2ycyebu3bt4na6srMxIkgtxaSAkx0SqK/AZRlQYIhtAyLChEcsj0ECAAAMABS4rJ0ADXJ8AAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_desc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1MjMyQjFCOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg1MjMyQjFDOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODUyMzJCMTk5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODUyMzJCMUE5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz69xJt+AAAAaElEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFlwSUhvnYrX6U+9sxlJciEuDYTkmEh1BUwM6APywhDZUHwuIxiG+FyKy3VDI9kMfgMBAgwAP+E336XXjQcAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
//height: 41px;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding-left: 8px;
height: 40px;
line-height: 40px;
box-sizing: border-box;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
//transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
}
.zb-table-header {
//overflow: hidden;
position: sticky;
top: 0;
z-index: 1;
width: fit-content;
background: #fafafa;
.item-th{
padding-left: 8px;
line-height: 39px;
height: 40px;
box-sizing: border-box;
}
.zb-stick-side{
position: sticky;
top: 0;
left: 0;
//border-right: solid 1rpx #dbdbdb;
box-sizing: border-box;
background: #fafafa;
//box-shadow: 6px 0 6px -4px #ccc;
}
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-header .zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
//transition: box-shadow 0.3s ease;
}
.scroll-left-fixed{
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px #ccc;
}
}
.odd{
background-color:rgba(249,249,249,0.6);
//height: 100%;
width: 100%;
}
.even{
background-color:white ;
//height: 100%;
width: 100%;
}
.zb-table-tbody {
.zb-stick-side{
position: sticky;
left: 0;
box-sizing: border-box;
background:white;
//box-shadow: 6px 0 6px -2px #ccc;
}
.odd{
background:#f9f9f9;
//height: 100%;
width: 100%;
}
.even{
background:white ;
//height: 100%;
width: 100%;
}
}
}
</style>

View File

@@ -1,26 +1,26 @@
<template> <template>
<!-- #ifdef H5 || APP-PLUS --> <!-- #ifdef H5 || APP-PLUS -->
<view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']"> <view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
<view class="zb-table-content"> <view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;"> <view class="zb-table-scroll" style="height: 100%;">
<template v-if="showHeader"> <template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;"> <view class="zb-table-header top-header-uni" style="height: 40px;">
<scroll-view class="zb-table-headers" <scroll-view class="zb-table-headers"
@scroll="handleTableScrollLeft" @scroll="handleTableScrollLeft"
scroll-x="true" scroll-x="true"
scroll-y="false" scroll-y="false"
id="tableHeaders" id="tableHeaders"
scroll-anchoring="true" scroll-anchoring="true"
:scroll-left="headerTableLeft" :scroll-left="headerTableLeft"
style="min-width: 17px;padding-bottom: 0px; style="min-width: 17px;padding-bottom: 0px;
background: #fafafa;height: 100%"> background: #fafafa;height: 100%">
<view class="zb-table-fixed" > <view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" > <view class="zb-table-thead" style="position: relative;" >
<view class="item-tr"> <view class="item-tr">
<view <view
@click="sortAction(item,index)" @click.stop="sortAction(item,index)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]" :class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{ :style="{
width:`${item.width?item.width:'100'}px`, width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none', flex:index===transColumns.length-1?1:'none',
minWidth:`${item.width?item.width:'100'}px`, minWidth:`${item.width?item.width:'100'}px`,
@@ -28,7 +28,7 @@
borderTop:`${border?'1px solid #e8e8e8':''}`, borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left' textAlign:item.align||'left'
}" }"
v-for="(item,index) in transColumns" :key="index"> v-for="(item,index) in transColumns" :key="index">
<template v-if="item.type==='selection'"> <template v-if="item.type==='selection'">
<view class="checkbox-item"> <view class="checkbox-item">
<tableCheckbox <tableCheckbox
@@ -39,26 +39,27 @@
{{ item.label }} {{ item.label }}
</template> </template>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</template> </template>
<template v-if="!data.length"> <template v-if="!data.length">
<view class="no-data">暂无数据~~</view> <view class="no-data">暂无数据~~</view>
</template> </template>
<scroll-view class="zb-table-body" ref="tableBody" scroll-x="true" scroll-y="true" id="tableBody" <scroll-view class="zb-table-body" ref="tableBody" scroll-x="true" scroll-y="true" id="tableBody"
:lower-threshold="10" :lower-threshold="10"
:upper-threshold="10" :upper-threshold="10"
@scrolltoupper="(e)=>debounce(scrollToLeft)(e)" @scroll="handleBodyScroll" :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" style=" height: calc(100% - 50px);" > @scrolltoupper="(e)=>debounce(scrollToLeft)(e)" @scroll="handleBodyScroll" :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" style=" height: calc(100% - 50px);" >
<view class="zb-table-fixed"> <view class="zb-table-fixed">
<view class="zb-table-tbody"> <view class="zb-table-tbody">
<view class="item-tr" <view class="item-tr"
v-for="(item,index) in transData" :key="item.key" > @click.stop="rowClick(item,index)"
<view v-for="(item,index) in transData" :key="item.key" >
:style="{ <view
:style="{
width:`${ite.width?ite.width:'100'}px`, width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none', flex:i===transColumns.length-1?1:'none',
minWidth:`${ite.width?ite.width:'100'}px`, minWidth:`${ite.width?ite.width:'100'}px`,
@@ -66,52 +67,55 @@
textAlign:ite.align||'left' textAlign:ite.align||'left'
}" }"
:class="['item-td',showStripe(index)]" :class="['item-td',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i"> v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'"> <template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%"> <view style="display: flex;align-items: center;height: 100%">
<view <view
v-for="ren,ind in ite.renders" v-for="ren,ind in ite.renders"
:key="ind" :key="ind"
@click.stop="$emit(ren.func,item,index)" @click.stop="$emit(ren.func,item,index)"
:style="{ :style="{
display:'flex', display:'flex',
alignItems: 'center', alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0' marginRight:ite.renders.length>1?'8px':'0'
}"> }">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button> <button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view>
</view>
</template>
<template v-else-if="ite.type==='selection'">
<view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
</view> </view>
</template> </view>
<template v-else> </template>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }} <template v-else-if="ite.type==='selection'">
</template> <view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
</view>
</template>
<template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="zb-table-fixed-left" v-if="isFixedLeft"> <view class="zb-table-fixed-left" v-if="isFixedLeft">
<template v-if="showHeader"> <template v-if="showHeader">
<view class="zb-table-header" style="height: 40px;display: flex"> <view class="zb-table-header" style="height: 40px;display: flex">
<view class="item-tr" style="" v-for="(item,index) in fixedLeftData" :key="index"> <view class="item-tr"
<view style=""
:style="{ @click.stop="rowClick(item,index)"
v-for="(item,index) in fixedLeftColumns" :key="index">
<view
:style="{
width:`${item.width?item.width:'100'}px`, width:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`, borderRight:`${border?'1px solid #e8e8e8':''}`,
borderTop:`${border?'1px solid #e8e8e8':''}`, borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left' textAlign:item.align||'left'
}" }"
@click="sortAction(item,0)" @click.stop="sortAction(item,0)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]" :class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
> >
<template v-if="item.type==='selection'"> <template v-if="item.type==='selection'">
<view class="checkbox-item"> <view class="checkbox-item">
<tableCheckbox <tableCheckbox
@@ -122,33 +126,34 @@
{{ item.label }} {{ item.label }}
</template> </template>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<view class="zb-table-body-outer center-header-uni" style="height: 100%;"> <view class="zb-table-body-outer center-header-uni" style="height: 100%;">
<scroll-view <scroll-view
scroll-y="true" scroll-y="true"
id="leftTableFixed" id="leftTableFixed"
:upper-threshold="15" :upper-threshold="15"
@scrolltoupper="(e)=>scrollToFixedLeft(e)" @scrolltoupper="(e)=>scrollToFixedLeft(e)"
@scroll="leftFixedScrollAction" @scroll="leftFixedScrollAction"
:scroll-top="leftFiexScrollTop" :scroll-top="leftFiexScrollTop"
class="zb-table-body-inner" class="zb-table-body-inner"
style=" height: calc(100% - 50px);"> style=" height: calc(100% - 50px);">
<view class="zb-table-fixed"> <view class="zb-table-fixed">
<view class="zb-table-tbody"> <view class="zb-table-tbody">
<view :class="['item-tr',showStripe(i)]" <view :class="['item-tr',showStripe(i)]"
v-for="(ite,i) in transData" v-for="(ite,i) in transData"
@click.stop="rowClick(ite,i)"
:key="ite.key" :key="ite.key"
style=""> style="">
<view :class="['item-td']" <view :class="['item-td']"
:style="{ :style="{
width:`${item.width?item.width:'100'}px`, width:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`, borderRight:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left' textAlign:item.align||'left'
}" }"
:key="item.key" :key="index"
v-for="(item,index) in fixedLeftData"> v-for="(item,index) in fixedLeftColumns">
<template v-if="item.type==='selection'"> <template v-if="item.type==='selection'">
<view class="checkbox-item"> <view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/> <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/>
@@ -159,28 +164,28 @@
</template> </template>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<!-- #endif --> <!-- #endif -->
<!-- #ifndef H5 || APP-PLUS --> <!-- #ifndef H5 || APP-PLUS -->
<view class="zb-table-applet"> <view class="zb-table-applet">
<view class="zb-table-content"> <view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;overflow: scroll"> <view class="zb-table-scroll" style="height: 100%;overflow: scroll">
<template v-if="showHeader"> <template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;"> <view class="zb-table-header top-header-uni" style="height: 40px;">
<view class="zb-table-fixed" > <view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" > <view class="zb-table-thead" style="position: relative;" >
<view class="item-tr"> <view class="item-tr">
<view <view
@click="sortAction(item,index)" @click.stop="sortAction(item,index)"
:class="['item-th',index <fixedLeftData.length&&'zb-stick-side',item.sorter&&`sorting${item.sorterMode||''}`]" :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{ :style="{
left:`${item.left}px`, left:`${item.left}px`,
width:`${item.width?item.width:'100'}px`, width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none', flex:index===transColumns.length-1?1:'none',
@@ -189,33 +194,34 @@
borderTop:`${border?'1px solid #e8e8e8':''}`, borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left' textAlign:item.align||'left'
}" }"
v-for="(item,index) in transColumns" :key="index"> v-for="(item,index) in transColumns" :key="index">
<template v-if="item.type==='selection'"> <template v-if="item.type==='selection'">
<view class="checkbox-item"> <view class="checkbox-item">
<tableCheckbox <tableCheckbox
:indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox> :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
</view> </view>
</template> </template>
<template v-else> <template v-else>
{{ item.label }} {{ item.label }}
</template> </template>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<template v-if="!data.length"> <template v-if="!data.length">
<view class="no-data">暂无数据~~</view> <view class="no-data">暂无数据~~</view>
</template> </template>
<view class="zb-table-fixed"> <view class="zb-table-fixed">
<view class="zb-table-tbody"> <view class="zb-table-tbody">
<view class="item-tr" <view class="item-tr"
v-for="(item,index) in transData" :key="item.key" > @click.stop="rowClick(item,index)"
<view v-for="(item,index) in transData" :key="item.key" >
:style="{ <view
:style="{
left:`${ite.left}px`, left:`${ite.left}px`,
width:`${ite.width?ite.width:'100'}px`, width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none', flex:i===transColumns.length-1?1:'none',
@@ -224,39 +230,39 @@
textAlign:ite.align||'left' textAlign:ite.align||'left'
}" }"
:class="['item-td', i <fixedLeftData.length&&'zb-stick-side',showStripe(index)]" :class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i"> v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'"> <template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%"> <view style="display: flex;align-items: center;height: 100%">
<view <view
v-for="ren,ind in ite.renders" v-for="ren,ind in ite.renders"
:key="ind" :key="ind"
@click.stop="$emit(ren.func,item,index)" @click.stop="$emit(ren.func,item,index)"
:style="{ :style="{
display:'flex', display:'flex',
alignItems: 'center', alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0' marginRight:ite.renders.length>1?'8px':'0'
}"> }">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button> <button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view> </view>
</view> </view>
</template> </template>
<template v-else-if="ite.type==='selection'"> <template v-else-if="ite.type==='selection'">
<view class="checkbox-item"> <view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/> <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
</view> </view>
</template> </template>
<template v-else> <template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }} {{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template> </template>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<script> <script>
import tableCheckbox from './table-checkbox.vue' import tableCheckbox from './table-checkbox.vue'
@@ -296,7 +302,7 @@ export default {
}, },
}, },
computed:{ computed:{
fixedLeftData(){ fixedLeftColumns(){
let arr = [] let arr = []
for(let i=0;i<this.columns.length;i++){ for(let i=0;i<this.columns.length;i++){
let item = this.columns[i] let item = this.columns[i]
@@ -390,13 +396,16 @@ export default {
let flag = this.columns.some(item=>item.type==='selection') let flag = this.columns.some(item=>item.type==='selection')
if(flag){ if(flag){
this.data.forEach(item=> { this.data.forEach(item=> {
item.checked = false if(item.checked==null){item.checked = false}
}) })
} }
}, },
mounted(){ mounted(){
}, },
methods: { methods: {
rowClick(row,index){
this.$emit('rowClick',row,index)
},
checkboxSelectedAll(e){ checkboxSelectedAll(e){
this.indeterminate = false this.indeterminate = false
if(e.checked){ if(e.checked){
@@ -505,9 +514,9 @@ export default {
sortAction(item,index){ sortAction(item,index){
this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc') this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
this.sortData(item) this.sortData(item)
// #ifndef H5 || APP-PLUS // #ifndef H5 || APP-PLUS
this.$forceUpdate() this.$forceUpdate()
// #endif // #endif
}, },
@@ -682,7 +691,7 @@ export default {
padding-left: 8px; padding-left: 8px;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
padding-right: 20px; padding-right: 20px;
box-sizing: border-box; box-sizing: border-box;
word-break:keep-all; /* 不换行 */ word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */ white-space:nowrap; /* 不换行 */
@@ -806,7 +815,7 @@ export default {
padding-left: 8px; padding-left: 8px;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
padding-right:20px; padding-right:20px;
box-sizing: border-box; box-sizing: border-box;
word-break:keep-all; /* 不换行 */ word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */ white-space:nowrap; /* 不换行 */

View File

@@ -1,547 +0,0 @@
<template>
<view :class="['zb-table','zb-table-fixed-header',(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;">
<template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;">
<scroll-view class="zb-table-headers"
@scroll="handleTableScrollLeft"
scroll-x="true"
scroll-y="false"
id="tableHeaders"
scroll-anchoring="true"
:scroll-left="headerTableLeft"
style="min-width: 17px;padding-bottom: 0px;
background: #fafafa;height: 100%">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" >
<view class="item-tr">
<view
@click="sortAction(item,index)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{
width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none',
minWidth:`${item.width?item.width:'100'}px`
}"
v-for="(item,index) in transColumns" :key="index">{{ item.label }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<template v-if="!data.length">
<view class="no-data">暂无数据~~</view>
</template>
<!-- #ifdef H5 -->
<scroll-view class="zb-table-body" ref="tableBody" scroll-x="true" scroll-y="true" id="tableBody"
:lower-threshold="10"
:upper-threshold="10"
@scrolltoupper="(e)=>debounce(scrollToLeft)(e)" @scroll="handleBodyScroll" :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" style=" height: calc(100% - 50px);" >
<!-- #endif -->
<!-- #ifndef H5 -->
<scroll-view class="zb-table-body" ref="tableBody"
:lower-threshold="5"
:upper-threshold="5"
scroll-x="true" scroll-y="true" id="tableBody"
@scrolltoupper="(e)=>scrollToLeft(e)" @scroll="handleBodyScroll" :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" style=" height: calc(100% - 50px);" >
<!-- #endif -->
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
v-for="(item,index) in transData" :key="item.key" >
<view
:style="{
width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none',
minWidth:`${ite.width?ite.width:'100'}px`
}"
:class="['item-td',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%">
<view
v-for="ren,ind in ite.renders"
:key="ind"
@click.stop="$emit(ren.func,item,index)"
:style="{
display:'flex',
alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0'
}">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view>
</view>
</template>
<template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="zb-table-fixed-left" v-if="isFixedLeft">
<template v-if="showHeader">
<view class="zb-table-header" style="height: 40px;">
<view class="item-tr" style="flex-direction: column;">
<view
:style="{
width:`${transColumns[0].width?transColumns[0].width:'100'}px`,
}"
@click="sortAction(transColumns[0],0)"
:class="['item-th',transColumns[0].sorter&&`sorting${transColumns[0].sorterMode||''}`]"
>{{ transColumns[0].label }}</view>
</view>
</view>
</template>
<view class="zb-table-body-outer center-header-uni" style="height: 100%;">
<scroll-view
scroll-y="true"
id="leftTableFixed"
:upper-threshold="15"
@scrolltoupper="(e)=>scrollToFixedLeft(e)"
@scroll="leftFixedScrollAction"
:scroll-top="leftFiexScrollTop"
class="zb-table-body-inner"
style=" height: calc(100% - 50px);">
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
style="flex-direction: column;">
<view :class="['item-td',showStripe(index)]"
:style="{
width:`${transColumns[0].width?transColumns[0].width:'100'}px`
}"
:key="item.key"
v-for="(item,index) in transData">{{item[transColumns[0].name]||transColumns[0].emptyString}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
itemDate:{
type:Object,
default:()=>{}
},
rowKey:Function,
columns:{
type:Array,
default:()=>[]
},
data:{
type:Array,
default:()=>[]
},
showHeader:{
type:Boolean,
default:true
},
stripe:{
type:Boolean,
default:true
},
fit:{
type:Boolean,
default:false
},
},
computed:{
isFixedLeft(){
if(!this.columns.length){
return false
}
if(!this.data.length){
return false
}
let [firstArr] = this.columns
return !!firstArr.fixed;
},
transColumns(){
if(this.fit){
this.columns.forEach(column=>{
if(column.type==="operation"&&column.renders){
let str = column.renders.reduce((prev,next)=>{
return prev.name+next.name
})
column.width = this.getTextWidth(str)+column.renders.length*40
}else {
let arr = [this.getTextWidth(column.label)]
this.data.forEach(data=>{
let str = (data[column.name]+'')
let width = this.getTextWidth(str)
arr.push(width)
})
column.width = Math.max(...arr)+12
}
})
return this.columns
}
this.columns.forEach(item=>{
if(item.type==="operation"&&item.renders){
let str = item.renders.reduce((prev,next)=>{
return prev.name+next.name
})
item.width = this.getTextWidth(str)+item.renders.length*40
}
item.emptyString = item.emptyString||'--'
})
return this.columns
},
transData(){
this.data.forEach((item,index)=>{
if(this.rowKey){
item.key = Object.freeze(this.rowKey(item))
}else {
item.key = index
}
})
return this.data
}
},
data() {
return {
button:[],
bodyTableLeft:0,
headerTableLeft:0,
lastScrollLeft:0,
leftFiexScrollTop:0,
bodyScrollTop:0,
currentDriver:null,
currentDriver1:null,
bodyTime:null,
bodyTime1:null,
headerTime:null,
debounceTime:null,
operation:{},
completedFlag:false,
}
},
methods: {
itemFilter(item,ite){
if(ite.filters&&ite.name){
let key = item[ite.name]
return ite.filters[key]||''
}
return item[ite.name]||ite.emptyString
},
// 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
getTextWidth(str) {
let flexWidth = 0
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符为字符分配8个单位宽度
flexWidth += 8
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符为字符分配15个单位宽度
flexWidth += 18
} else {
// 其他种类字符为字符分配8个单位宽度
flexWidth += 8
}
}
return flexWidth
},
width(item){
return `${item.width?item.width:'100'}px`
},
showStripe(index){
if(this.currentDriver)return
if(this.stripe){
return (index % 2) != 0?'odd':'even'
}else{
return ''
}
},
//验证字符串是否是数字
checkNumber(theObj) {
var reg = /^[0-9]+.?[0-9]*$/;
if (reg.test(theObj)) {
return true;
}
return false;
},
isDate(data){
if(isNaN(data)&&!isNaN(Date.parse(data))){
return true
}
return false
},
sortAction(item,index){
this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
this.sortData(item)
},
sortData(item){
let key = item.name
if(item.sorterMode==='_asc'){
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return a[key]-b[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return a1-b1
}
})
}else {
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return b[key]-a[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return b1-a1
}
})
}
},
throttle(method,delay=60){
let time = null
return (...args)=>{
if(!time){
time = setTimeout(()=>{
method(...args)
time = null;
},delay)
}
}
},
debounce(method,delay=1000){
return (...args)=>{
this.debounceTime&&clearTimeout(this.debounceTime)
this.debounceTime = setTimeout(()=>{
method(...args)
},delay)
}
},
handleBodyScroll(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.headerTableLeft = e.detail.scrollLeft
this.leftFiexScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
leftFixedScrollAction(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
scrollToLeft(e){
if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
this.currentDriver1 = e.currentTarget.id
if(e.detail.direction==='left'&&this.headerTableLeft<10){
this.headerTableLeft = 0
}else if(e.detail.direction==='top'&&this.leftFiexScrollTop<10){
this.leftFiexScrollTop = 0
}
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver1=null
},200)
},
scrollToFixedLeft(e){
if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
this.currentDriver1 = e.currentTarget.id
if(e.detail.direction==='top'&&this.bodyScrollTop<10){
this.bodyScrollTop = 0
}
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver1=null
},200)
},
handleTableScrollLeft(e,type){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyTableLeft = e.detail.scrollLeft
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
}
}
}
</script>
<style lang="scss">
.zb-table-fixed-left{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
.zb-table-header{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
</style>
<style lang="scss" scoped>
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
}
.no-data{
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e8e8e8;
}
.zb-table{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
}
.sorting{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczRkE5Qjk2OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczRkE5Qjk3OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzNGQTlCOTQ5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzNGQTlCOTU5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4R7rKqAAAAWklEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFnI8RYIKCsrM5LkQlwaCMkxkeoKfIYRFYbIBhAybGjE8gg0ECDAAI+ULEsz8LFkAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_asc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlDMzQ5NTk4OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlDMzQ5NTk5OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OUMzNDk1OTY5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OUMzNDk1OTc5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4u6TUfAAAAdElEQVR42mL8//8/AzUBEwOVweA3kIVUDdJbp8LZT72zyXMh0JD/IIzLEJIMhBmEzMZnKCO+ZINsGDIAGshIsgtxGUZIjnHQJ2ycyebu3bt4na6srMxIkgtxaSAkx0SqK/AZRlQYIhtAyLChEcsj0ECAAAMABS4rJ0ADXJ8AAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_desc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1MjMyQjFCOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg1MjMyQjFDOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODUyMzJCMTk5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODUyMzJCMUE5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz69xJt+AAAAaElEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFlwSUhvnYrX6U+9sxlJciEuDYTkmEh1BUwM6APywhDZUHwuIxiG+FyKy3VDI9kMfgMBAgwAP+E336XXjQcAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
//height: 41px;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding-left: 8px;
height: 40px;
line-height: 40px;
box-sizing: border-box;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
//transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
}
.zb-table-fixed-left .zb-table-header{
overflow-y: hidden;
}
.zb-table-header {
overflow: hidden;
background: #fafafa;
.item-th{
padding-left: 8px;
line-height: 39px;
height: 40px;
box-sizing: border-box;
}
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-header .zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
//transition: box-shadow 0.3s ease;
}
.scroll-left-fixed{
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px #ccc;
}
}
.odd{
background-color:rgba(249,249,249,0.6);
//height: 100%;
width: 100%;
}
.even{
background-color:white ;
//height: 100%;
width: 100%;
}
</style>

View File

@@ -1,377 +0,0 @@
<template>
<view class="zb-table zb-table-fixed-header zb-table-layout-fixed zb-table-default zb-table-scroll-position-left">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;">
<view class="zb-table-header top-header-uni" style="height: 50px;">
<scroll-view class="zb-table-headers"
@scroll="handleTableScrollLeft"
scroll-x="true"
scroll-y="true"
id="tableHeaders"
scroll-anchoring="true"
:scroll-left="headerTableLeft"
style="min-width: 17px;padding-bottom: 0px;
background: #fafafa;height: 100%">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;">
<view class="item-tr">
<view class="item-th">header1</view>
<view class="item-th ">header2</view>
<view class="item-th">header3</view>
<view class="item-th">header4</view>
<view class="item-th">header5</view>
<view class="item-th">header6</view>
<view class="item-th">header7</view>
<view class="item-th">header8</view>
<view class="item-th">header9</view>
<view class="item-th">header10</view>
</view>
</view>
</view>
</scroll-view>
</view>
<scroll-view class="zb-table-body"
ref="tableBody"
scroll-x="true"
scroll-y="true"
id="tableBody"
@scrolltoupper="scrollToLeft"
@scroll="handleBodyScroll"
:scroll-left="bodyTableLeft"
:scroll-top="bodyScrollTop"
style=" height: calc(100% - 50px);" >
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
<view class="item-tr">
<view class="item-td">Edrward 1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td">Edrward 9</view>
<view class="item-td">Edrward 10</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="zb-table-fixed-left">
<view class="zb-table-header">
<view class="item-tr" style="flex-direction: column;">
<view class="item-td">header1</view>
</view>
</view>
<view class="zb-table-body-outer center-header-uni" style="height: 100%;">
<scroll-view
scroll-y="true"
id="leftTableFixed"
@scroll="leftFixedScrollAction"
:scroll-top="leftFiexScrollTop"
class="zb-table-body-inner"
style=" height: calc(100% - 50px);">
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr" style="flex-direction: column;">
<view class="item-td">header1</view>
<view class="item-td">Edrward 2</view>
<view class="item-td">Edrward 3</view>
<view class="item-td">Edrward 4</view>
<view class="item-td">Edrward 5</view>
<view class="item-td">Edrward 6</view>
<view class="item-td">Edrward 7</view>
<view class="item-td">Edrward 8</view>
<view class="item-td ">Edrward 9</view>
<view class="item-td ">Edrward 10</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
itemDate:{
type:Object,
default:()=>{}
}
},
computed:{
// dataSource(){
// let columns = itemDate.columns[0].children;
// columns = columns.map(function(column){
// return {
// title: column.title,
// data: column.dataIndex,
// dataType: column.dataType
// };
// });
// columns.forEach(function(column){
// if(column.dataType === "Number"){
// dataSource.forEach(function(data){
// var value = data[column.data];
// var toFixed = 0;
// if(utils.check.decimal(value)){
// toFixed = 2;
// }
// data[column.data] = utils.toLocaleString(data[column.data], toFixed);
// });
// }
// else if(column.dataType === "Float"){
// dataSource.forEach(function(data){
// data[column.data] = utils.toLocaleString(data[column.data], 2);
// });
// }
// });
// // return
// }
},
data() {
return {
bodyTableLeft:0,
headerTableLeft:0,
lastScrollLeft:0,
leftFiexScrollTop:0,
bodyScrollTop:0,
currentDriver:null,
currentDriver1:null,
bodyTime:null,
bodyTime1:null,
headerTime:null,
}
},
mounted(){
},
methods: {
handleBodyScroll(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.headerTableLeft = e.detail.scrollLeft
this.leftFiexScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
leftFixedScrollAction(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
scrollToLeft(e){
if(e.detail.direction==='left'){
this.headerTableLeft = 0
}else if(e.detail.direction==='top'){
this.leftFiexScrollTop = 0
}
},
handleTableScrollLeft(e,type){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyTableLeft = e.detail.scrollLeft
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
}
}
}
</script>
<style lang="scss" scoped>
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
}
.zb-table{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding: 16px 16px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
padding: 16px 16px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
}
.zb-table-fixed-left .zb-table-header{
overflow-y: hidden;
}
.zb-table-header {
overflow: hidden;
background: #fafafa;
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-header .zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
transition: box-shadow 0.3s ease;
}
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px gray;
}
</style>

View File

@@ -5,19 +5,6 @@
"style": { "style": {
"navigationBarTitleText": "uni-app" "navigationBarTitleText": "uni-app"
} }
},
{
"path": "pages/test/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},
{
"path": "pages/scroll/index",
"style": {
"navigationBarTitleText": "uni-app"
}
} }
], ],
"globalStyle": { "globalStyle": {

View File

@@ -7,6 +7,7 @@
:columns="column" :columns="column"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
:border="true" :border="true"
@@ -22,6 +23,7 @@
:columns="column1" :columns="column1"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
@@ -37,6 +39,7 @@
:columns="column1" :columns="column1"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
:border="true" :border="true"
@@ -52,6 +55,7 @@
:columns="column2" :columns="column2"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
:border="true" :border="true"
@@ -67,6 +71,7 @@
:columns="column3" :columns="column3"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
:border="true" :border="true"
@@ -82,6 +87,7 @@
:columns="column4" :columns="column4"
:stripe="true" :stripe="true"
:fit="false" :fit="false"
@rowClick="rowClick"
@toggleRowSelection="toggleRowSelection" @toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection" @toggleAllSelection="toggleAllSelection"
:border="true" :border="true"
@@ -96,11 +102,11 @@
</template> </template>
<script> <script>
import ZbTable from '@/components/zb-table/index.vue' // import ZbTable from '@/components/zb-table/index.vue'
import {column1,column2,column3,column4} from './all.js' import {column1,column2,column3,column4} from './all.js'
export default { export default {
components:{ components:{
ZbTable // ZbTable
}, },
data() { data() {
return { return {
@@ -148,6 +154,7 @@
name: '', name: '',
province: '上海', province: '上海',
sex:'1', sex:'1',
checked:true,
id:"20", id:"20",
age:'', age:'',
city: '普陀区', city: '普陀区',
@@ -162,6 +169,7 @@
id:"2", id:"2",
age:12, age:12,
city: '普陀区', city: '普陀区',
address: '上海市普', address: '上海市普',
zip: 200333 zip: 200333
}, },
@@ -297,6 +305,14 @@
title:'点击单选' title:'点击单选'
}) })
console.log('单选',checked,arr) console.log('单选',checked,arr)
},
rowClick(row,index){
uni.showToast({
icon:'none',
duration:3000,
title:'单击某行'
})
console.log('单击某行',row,index)
} }
}, },

View File

@@ -1,135 +0,0 @@
<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title uni-common-mt">
Vertical Scroll
<text>\n纵向滚动</text>
</view>
<view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y" @scrolltoupper="upper" @scrolltolower="lower"
@scroll="scroll">
<view id="demo1" class="scroll-view-item uni-bg-red" :key="key(item)" v-for="item in datas">A</view>
</scroll-view>
</view>
<view @tap="goTop" class="uni-link uni-center uni-common-mt">
点击这里返回顶部
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
scrollTop: 0,
old: {
scrollTop: 0
},
datas:[
{
date: '2016-05-02',
name: '',
province: '上海',
sex:'1',
id:"1",
age:'',
city: '普陀区',
address: '上海市普上海市普上海市普上海市普',
zip: 200333
},
{
date: '2016-05-01',
name: '王小虎2',
province: '上海',
sex:'0',
id:"2",
age:12,
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎3',
province: '上海',
sex:1,
id:"3",
age:'15',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-04-02',
name: '王小虎4',
province: '上海',
sex:1,
age:'11',
id:"4",
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-03-02',
name: '王小虎5',
province: '上海',
sex:1,
age:'14',
id:"5",
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2014-05-02',
name: '王小虎6',
province: '上海',
sex:1,
id:"6",
age:'12',
city: '普陀区',
address: '上海市普',
zip: 200333
},
]
}
},
methods: {
key(item){
console.log(111111)
return item.id
},
upper: function(e) {
// console.log(e)
},
lower: function(e) {
// console.log(e)
},
scroll: function(e) {
// console.log(e)
this.old.scrollTop = e.detail.scrollTop
},
goTop: function(e) {
this.scrollTop = this.old.scrollTop
this.$nextTick(() => {
this.scrollTop = 0
});
uni.showToast({
icon:"none",
title:"纵向滚动 scrollTop 值已被修改为 0"
})
}
}
}
</script>
<style>
.scroll-Y{
height: 100px;
}
.scroll-view-item{
width: 100%;
height: 100px;
}
</style>

View File

@@ -1,176 +0,0 @@
<template>
<view class="content">
<zb-table
:show-header="true"
:columns="column"
:stripe="true"
:fit="false"
:data="data"></zb-table>
</view>
</template>
<script>
import ZbTable from '@/components/zb-table1/index.vue'
export default {
components:{
ZbTable
},
data() {
return {
title: 'Hello',
column:[
{ name: 'name', label: '姓名',fixed:true,width:80,emptyString:'--' },
{ name: 'age', label: '年纪',sorter:true },
{ name: 'sex', label: '性别' },
{ name: 'address', label: '地址' },
{ name: 'date', label: '日期',sorter:true },
{ name: 'province', label: '省份' },
{ name: 'city', label: '城市' },
{ name: 'zip', label: '邮编' },
],
data1:[],
data:[
{
date: '2016-05-02',
name: '',
province: '上海',
sex:'男',
age:'',
city: '普陀区',
address: '上海市普上海市普上海市普上海市普',
zip: 200333
},
{
date: '2016-05-01',
name: '王小虎2',
province: '上海',
sex:'男',
age:12,
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎3',
province: '上海',
sex:'男',
age:'15',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-04-02',
name: '王小虎4',
province: '上海',
sex:'男',
age:'11',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-03-02',
name: '王小虎5',
province: '上海',
sex:'男',
age:'14',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2014-05-02',
name: '王小虎6',
province: '上海',
sex:'男',
age:'12',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2019-05-02',
name: '王小虎7',
province: '上海',
sex:'男',
age:'10',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2012-05-02',
name: '王小虎8',
province: '上海',
sex:'男',
age:'29',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
}
]
}
},
onLoad() {
},
mounted(){
// setTimeout(()=>{
// this.data = this.data1
// },2000)
},
methods: {
}
}
</script>
<style>
.content{
height: 600rpx;
}
</style>

View File

@@ -18,7 +18,12 @@
| 事件名自定义 | 取决于type类型为operation的 renders参数里面 func 的参数名 | Function |(row,index)=>{} | -- |否 | | 事件名自定义 | 取决于type类型为operation的 renders参数里面 func 的参数名 | Function |(row,index)=>{} | -- |否 |
| toggleRowSelection | 用于多选表格,切换某一行的选中状态,第一个参数代表选中状态,参数二代表选中的对象 | Function |(selected ,array)=>{} | -- |否 | | toggleRowSelection | 用于多选表格,切换某一行的选中状态,第一个参数代表选中状态,参数二代表选中的对象 | Function |(selected ,array)=>{} | -- |否 |
| toggleAllSelection | 用于多选表格,切换所有行的选中状态 ,第一个参数代表选中状态,参数二代表选中的对象| Function |(selected ,array)=>{} | -- |否 | | toggleAllSelection | 用于多选表格,切换所有行的选中状态 ,第一个参数代表选中状态,参数二代表选中的对象| Function |(selected ,array)=>{} | -- |否 |
| rowClick | 单击某行 第一个参数代表选中对象参数二代表选中的index| Function |(row ,index)=>{} | -- |否 |
## data 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| checked | 是否被勾选 | boolean |true,false | 无 |
## column 属性 ## column 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 | | 参数 | 说明 | 类型 | 可选值 | 默认值 |

View File

@@ -0,0 +1,40 @@
## 1.1.12022-03-10
新增单击事件
## 1.1.02022-03-10
- 增加单击事件
## 1.1.02022-03-10
- 增加checkbox功能 ,进行优化
## 1.0.112022-03-09
- 修改小程序中排序问题
## 1.0.102022-03-09
- 做了兼容性处理
## 1.0.82022-03-09
- 进行优化滚动防止 多次计算
## 1.0.72022-03-09
- 修改一些问题 新增过滤器
## 1.0.62022-03-08
- 修改样式 按钮自适应宽度
## 1.0.52022-03-08
- 新增按钮 修改问题
## 1.0.42022-03-04
- 增加空占位符"--"
## 1.0.32022-03-02
- 新增表格斑马纹配置、列宽配置、表头显示配置
## 1.0.22022-03-02
- 新增排序功能,优化样式
## 1.0.12022-03-01
- 可以传入动态数据,可以对左边列表进行是否固定首列
## 1.0.02022-03-01
- 初始化

View File

@@ -0,0 +1,180 @@
<template>
<view class="uni-table-checkbox" @click.stop="selected">
<view v-if="!indeterminate" class="checkbox__inner" :class="{'is-checked':isChecked,'is-disable':isDisabled}">
<view class="checkbox__inner-icon"></view>
</view>
<view v-else class="checkbox__inner checkbox--indeterminate">
<view class="checkbox__inner-icon"></view>
</view>
</view>
</template>
<script>
export default {
name: 'TableCheckbox',
emits:['checkboxSelected'],
props: {
indeterminate: {
type: Boolean,
default: false
},
checked: {
type: [Boolean,String],
default: false
},
disabled: {
type: Boolean,
default: false
},
index: {
type: Number,
default: -1
},
cellData: {
type: Object,
default () {
return {}
}
}
},
watch:{
checked(newVal){
if(typeof this.checked === 'boolean'){
this.isChecked = newVal
}else{
this.isChecked = true
}
},
indeterminate(newVal){
this.isIndeterminate = newVal
}
},
data() {
return {
isChecked: false,
isDisabled: false,
isIndeterminate:false
}
},
created() {
if(typeof this.checked === 'boolean'){
this.isChecked = this.checked
}
this.isDisabled = this.disabled
},
methods: {
selected() {
if (this.isDisabled) return
this.isIndeterminate = false
this.isChecked = !this.isChecked
console.log('===',this.indeterminate,this.isChecked)
this.$emit('checkboxSelected', {
checked: this.isChecked,
data: this.cellData
})
}
}
}
</script>
<style lang="scss">
$checked-color: #007aff;
$border-color: #DCDFE6;
$disable:0.4;
.uni-table-checkbox {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
position: relative;
margin: 5px 0;
cursor: pointer;
// 多选样式
.checkbox__inner {
/* #ifndef APP-NVUE */
flex-shrink: 0;
box-sizing: border-box;
/* #endif */
position: relative;
width: 16px;
height: 16px;
border: 1px solid $border-color;
border-radius: 2px;
background-color: #fff;
z-index: 1;
.checkbox__inner-icon {
position: absolute;
/* #ifdef APP-NVUE */
top: 2px;
/* #endif */
/* #ifndef APP-NVUE */
top: 2px;
/* #endif */
left: 5px;
height: 7px;
width: 3px;
border: 1px solid #fff;
border-left: 0;
border-top: 0;
opacity: 0;
transform-origin: center;
transform: rotate(45deg);
box-sizing: content-box;
}
&.checkbox--indeterminate {
border-color: $checked-color;
background-color: $checked-color;
.checkbox__inner-icon {
position: absolute;
opacity: 1;
transform: rotate(0deg);
height: 2px;
top: 0;
bottom: 0;
margin: auto;
left: 0px;
right: 0px;
bottom: 0;
width: auto;
border: none;
border-radius: 2px;
transform: scale(0.5);
background-color: #fff;
}
}
&:hover{
border-color: $checked-color;
}
// 禁用
&.is-disable {
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
background-color: #F2F6FC;
border-color: $border-color;
}
// 选中
&.is-checked {
border-color: $checked-color;
background-color: $checked-color;
.checkbox__inner-icon {
opacity: 1;
transform: rotate(45deg);
}
// 选中禁用
&.is-disable {
opacity: $disable;
}
}
}
}
</style>

View File

@@ -0,0 +1,920 @@
<template>
<!-- #ifdef H5 || APP-PLUS -->
<view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;">
<template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;">
<scroll-view class="zb-table-headers"
@scroll="handleTableScrollLeft"
scroll-x="true"
scroll-y="false"
id="tableHeaders"
scroll-anchoring="true"
:scroll-left="headerTableLeft"
style="min-width: 17px;padding-bottom: 0px;
background: #fafafa;height: 100%">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" >
<view class="item-tr">
<view
@click.stop="sortAction(item,index)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{
width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none',
minWidth:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left'
}"
v-for="(item,index) in transColumns" :key="index">
<template v-if="item.type==='selection'">
<view class="checkbox-item">
<tableCheckbox
:indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
</view>
</template>
<template v-else>
{{ item.label }}
</template>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<template v-if="!data.length">
<view class="no-data">暂无数据~~</view>
</template>
<scroll-view class="zb-table-body" ref="tableBody" scroll-x="true" scroll-y="true" id="tableBody"
:lower-threshold="10"
:upper-threshold="10"
@scrolltoupper="(e)=>debounce(scrollToLeft)(e)" @scroll="handleBodyScroll" :scroll-left="bodyTableLeft" :scroll-top="bodyScrollTop" style=" height: calc(100% - 50px);" >
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
@click.stop="rowClick(item,index)"
v-for="(item,index) in transData" :key="item.key" >
<view
:style="{
width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none',
minWidth:`${ite.width?ite.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
textAlign:ite.align||'left'
}"
:class="['item-td',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%">
<view
v-for="ren,ind in ite.renders"
:key="ind"
@click.stop="$emit(ren.func,item,index)"
:style="{
display:'flex',
alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0'
}">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view>
</view>
</template>
<template v-else-if="ite.type==='selection'">
<view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
</view>
</template>
<template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="zb-table-fixed-left" v-if="isFixedLeft">
<template v-if="showHeader">
<view class="zb-table-header" style="height: 40px;display: flex">
<view class="item-tr"
style=""
@click.stop="rowClick(item,index)"
v-for="(item,index) in fixedLeftColumns" :key="index">
<view
:style="{
width:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left'
}"
@click.stop="sortAction(item,0)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
>
<template v-if="item.type==='selection'">
<view class="checkbox-item">
<tableCheckbox
:indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
</view>
</template>
<template v-else>
{{ item.label }}
</template>
</view>
</view>
</view>
</template>
<view class="zb-table-body-outer center-header-uni" style="height: 100%;">
<scroll-view
scroll-y="true"
id="leftTableFixed"
:upper-threshold="15"
@scrolltoupper="(e)=>scrollToFixedLeft(e)"
@scroll="leftFixedScrollAction"
:scroll-top="leftFiexScrollTop"
class="zb-table-body-inner"
style=" height: calc(100% - 50px);">
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view :class="['item-tr',showStripe(i)]"
v-for="(ite,i) in transData"
@click.stop="rowClick(ite,i)"
:key="ite.key"
style="">
<view :class="['item-td']"
:style="{
width:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left'
}"
:key="index"
v-for="(item,index) in fixedLeftColumns">
<template v-if="item.type==='selection'">
<view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/>
</view>
</template>
<template v-else>
{{ite[item.name]||item.emptyString}}
</template>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- #endif -->
<!-- #ifndef H5 || APP-PLUS -->
<view class="zb-table-applet">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;overflow: scroll">
<template v-if="showHeader">
<view class="zb-table-header top-header-uni" style="height: 40px;">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" >
<view class="item-tr">
<view
@click.stop="sortAction(item,index)"
:class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{
left:`${item.left}px`,
width:`${item.width?item.width:'100'}px`,
flex:index===transColumns.length-1?1:'none',
minWidth:`${item.width?item.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
borderTop:`${border?'1px solid #e8e8e8':''}`,
textAlign:item.align||'left'
}"
v-for="(item,index) in transColumns" :key="index">
<template v-if="item.type==='selection'">
<view class="checkbox-item">
<tableCheckbox
:indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
</view>
</template>
<template v-else>
{{ item.label }}
</template>
</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="!data.length">
<view class="no-data">暂无数据~~</view>
</template>
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
@click.stop="rowClick(item,index)"
v-for="(item,index) in transData" :key="item.key" >
<view
:style="{
left:`${ite.left}px`,
width:`${ite.width?ite.width:'100'}px`,
flex:i===transColumns.length-1?1:'none',
minWidth:`${ite.width?ite.width:'100'}px`,
borderRight:`${border?'1px solid #e8e8e8':''}`,
textAlign:ite.align||'left'
}"
:class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',showStripe(index)]"
v-for="(ite,i) in transColumns" :key="i">
<template v-if="ite.type==='operation'">
<view style="display: flex;align-items: center;height: 100%">
<view
v-for="ren,ind in ite.renders"
:key="ind"
@click.stop="$emit(ren.func,item,index)"
:style="{
display:'flex',
alignItems: 'center',
marginRight:ite.renders.length>1?'8px':'0'
}">
<button :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
</view>
</view>
</template>
<template v-else-if="ite.type==='selection'">
<view class="checkbox-item">
<tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
</view>
</template>
<template v-else>
{{ ite.filters?itemFilter(item,ite):item[ite.name]||ite.emptyString }}
</template>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- #endif -->
</template>
<script>
import tableCheckbox from './table-checkbox.vue'
export default {
components:{
tableCheckbox
},
props:{
itemDate:{
type:Object,
default:()=>{}
},
rowKey:Function,
columns:{
type:Array,
default:()=>[]
},
data:{
type:Array,
default:()=>[]
},
showHeader:{
type:Boolean,
default:true
},
border:{
type:Boolean,
default:false
},
stripe:{
type:Boolean,
default:true
},
fit:{
type:Boolean,
default:false
},
},
computed:{
fixedLeftColumns(){
let arr = []
for(let i=0;i<this.columns.length;i++){
let item = this.columns[i]
if(item.fixed){
if(i===0){
item.left = 0
}else {
item.left = this.columns[i-1].width
}
arr.push(item)
}else {
break
}
}
return arr
},
isFixedLeft(){
if(!this.columns.length){
return false
}
if(!this.data.length){
return false
}
let [firstArr] = this.columns
return !!firstArr.fixed;
},
transColumns(){
if(this.fit){
this.columns.forEach(column=>{
if(column.type==="operation"&&column.renders){
let str = column.renders.reduce((prev,next)=>{
return prev.name+next.name
})
column.width = this.getTextWidth(str)+column.renders.length*40
}else {
let arr = [this.getTextWidth(column.label)]
this.data.forEach(data=>{
let str = (data[column.name]+'')
let width = this.getTextWidth(str)
arr.push(width)
})
column.width = Math.max(...arr)+12
}
})
return this.columns
}
this.columns.forEach(item=>{
if(item.type==="operation"&&item.renders){
let str = item.renders.reduce((prev,next)=>{
return prev.name+next.name
})
item.width = this.getTextWidth(str)+item.renders.length*40
}
item.emptyString = item.emptyString||'--'
})
return this.columns
},
transData(){
this.data.forEach((item,index)=>{
if(this.rowKey){
item.key = Object.freeze(this.rowKey(item))||Date.now()
}else {
item.key = index
}
})
return this.data
}
},
data() {
return {
button:[],
bodyTableLeft:0,
headerTableLeft:0,
lastScrollLeft:0,
leftFiexScrollTop:0,
bodyScrollTop:0,
currentDriver:null,
currentDriver1:null,
bodyTime:null,
bodyTime1:null,
headerTime:null,
debounceTime:null,
operation:{},
completedFlag:false,
selectArr:[],
indeterminate:false,
checkedAll:false
}
},
created(){
let flag = this.columns.some(item=>item.type==='selection')
if(flag){
this.data.forEach(item=> {
if(item.checked==null){item.checked = false}
})
}
},
mounted(){
},
methods: {
rowClick(row,index){
this.$emit('rowClick',row,index)
},
checkboxSelectedAll(e){
this.indeterminate = false
if(e.checked){
this.selectArr = []
this.checkedAll = true
this.data.forEach(item=>{
this.$set(item,'checked',true)
this.selectArr.push(item)
})
}else{
this.checkedAll = false
this.data.forEach(item=>{
this.$set(item,'checked',false)
})
this.selectArr = []
}
// #ifndef H5 || APP-PLUS
this.$forceUpdate()
// #endif
this.$emit('toggleAllSelection',e.checked,this.selectArr)
},
checkboxSelected(e,item){
// #ifdef H5 || APP-PLUS
this.$set(item,'checked',e.checked)
// #endif
// #ifndef H5 || APP-PLUS
this.data.forEach(item=>{
if(item.key===e.data.key){
item.checked = e.checked
}
})
// #endif
item.checked = e.checked
e.data.checked = e.checked
if(e.checked){
this.selectArr.push(e.data)
}else{
this.selectArr = this.selectArr.filter(item=>item.key!==e.data.key)
}
if(this.selectArr.length===this.data.length){
this.indeterminate = false
this.checkedAll = true
}else{
this.indeterminate = true
this.checkedAll = false
}
if(!this.selectArr.length){
this.checkedAll = false
this.indeterminate = false
}
// #ifndef H5 || APP-PLUS
this.$forceUpdate()
// #endif
this.$emit('toggleRowSelection',e.checked,this.selectArr)
},
itemFilter(item,ite){
if(ite.filters&&ite.name){
let key = item[ite.name]
return ite.filters[key]||''
}
return item[ite.name]||ite.emptyString
},
// 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
getTextWidth(str) {
let flexWidth = 0
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符为字符分配8个单位宽度
flexWidth += 8
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符为字符分配15个单位宽度
flexWidth += 18
} else {
// 其他种类字符为字符分配8个单位宽度
flexWidth += 8
}
}
return flexWidth
},
width(item){
return `${item.width?item.width:'100'}px`
},
showStripe(index){
if(this.currentDriver)return
if(this.stripe){
return (index % 2) != 0?'odd':'even'
}else{
return ''
}
},
//验证字符串是否是数字
checkNumber(theObj) {
var reg = /^[0-9]+.?[0-9]*$/;
if (reg.test(theObj)) {
return true;
}
return false;
},
isDate(data){
if(isNaN(data)&&!isNaN(Date.parse(data))){
return true
}
return false
},
sortAction(item,index){
this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
this.sortData(item)
// #ifndef H5 || APP-PLUS
this.$forceUpdate()
// #endif
},
sortData(item){
let key = item.name
if(item.sorterMode==='_asc'){
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return a[key]-b[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return a1-b1
}
})
}else {
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return b[key]-a[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return b1-a1
}
})
}
},
throttle(method,delay=60){
let time = null
return (...args)=>{
if(!time){
time = setTimeout(()=>{
method(...args)
time = null;
},delay)
}
}
},
debounce(method,delay=1000){
return (...args)=>{
this.debounceTime&&clearTimeout(this.debounceTime)
this.debounceTime = setTimeout(()=>{
method(...args)
},delay)
}
},
handleBodyScroll(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.headerTableLeft = e.detail.scrollLeft
this.leftFiexScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
leftFixedScrollAction(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
scrollToLeft(e){
if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
this.currentDriver1 = e.currentTarget.id
if(e.detail.direction==='left'&&this.headerTableLeft<10){
this.headerTableLeft = 0
}else if(e.detail.direction==='top'&&this.leftFiexScrollTop<10){
this.leftFiexScrollTop = 0
}
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver1=null
},200)
},
scrollToFixedLeft(e){
if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
this.currentDriver1 = e.currentTarget.id
if(e.detail.direction==='top'&&this.bodyScrollTop<10){
this.bodyScrollTop = 0
}
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver1=null
},200)
},
handleTableScrollLeft(e,type){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyTableLeft = e.detail.scrollLeft
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
}
}
}
</script>
<style lang="scss">
.zb-table-fixed-left{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
.zb-table-header{
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
}
</style>
<style lang="scss" scoped>
.checkbox-item{
display: flex;align-items: center;justify-content: center;width: 100%;height: 100%
}
.no-data{
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e8e8e8;
}
.zb-table{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
//height: 41px;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding-left: 8px;
height: 40px;
line-height: 40px;
padding-right: 20px;
box-sizing: border-box;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
//transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
padding-right: 20px;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
}
.zb-table-fixed-left .zb-table-header{
overflow-y: hidden;
}
.zb-table-header {
overflow: hidden;
background: #fafafa;
.item-th{
padding-left: 8px;
line-height: 39px;
height: 40px;
box-sizing: border-box;
}
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
//transition: box-shadow 0.3s ease;
}
.odd{
background-color:rgba(249,249,249,0.6);
//height: 100%;
width: 100%;
}
.even{
background-color:white ;
//height: 100%;
width: 100%;
}
}
.scroll-left-fixed{
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px #ccc;
}
}
.sorting{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczRkE5Qjk2OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczRkE5Qjk3OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzNGQTlCOTQ5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzNGQTlCOTU5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4R7rKqAAAAWklEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFnI8RYIKCsrM5LkQlwaCMkxkeoKfIYRFYbIBhAybGjE8gg0ECDAAI+ULEsz8LFkAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_asc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlDMzQ5NTk4OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlDMzQ5NTk5OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OUMzNDk1OTY5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OUMzNDk1OTc5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4u6TUfAAAAdElEQVR42mL8//8/AzUBEwOVweA3kIVUDdJbp8LZT72zyXMh0JD/IIzLEJIMhBmEzMZnKCO+ZINsGDIAGshIsgtxGUZIjnHQJ2ycyebu3bt4na6srMxIkgtxaSAkx0SqK/AZRlQYIhtAyLChEcsj0ECAAAMABS4rJ0ADXJ8AAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_desc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1MjMyQjFCOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg1MjMyQjFDOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODUyMzJCMTk5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODUyMzJCMUE5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz69xJt+AAAAaElEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFlwSUhvnYrX6U+9sxlJciEuDYTkmEh1BUwM6APywhDZUHwuIxiG+FyKy3VDI9kMfgMBAgwAP+E336XXjQcAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.zb-table-applet{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
width: fit-content;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
//height: 41px;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding-left: 8px;
height: 40px;
line-height: 40px;
padding-right:20px;
box-sizing: border-box;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
//transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
padding-right: 20px;
word-break:keep-all; /* 不换行 */
white-space:nowrap; /* 不换行 */
overflow:hidden; /* 内容超出宽度时隐藏超出部分的内容 */
text-overflow:ellipsis; /* 当对象内文本溢出时显示省略标记(...) 需与overflow:hidden;一起使用。*/
overflow-wrap: break-word;
}
.zb-table-header {
//overflow: hidden;
position: sticky;
top: 0;
z-index: 1;
width: fit-content;
background: #fafafa;
.item-th{
padding-left: 8px;
line-height: 39px;
height: 40px;
box-sizing: border-box;
}
.zb-stick-side{
position: sticky;
top: 0;
left: 0;
//border-right: solid 1rpx #dbdbdb;
box-sizing: border-box;
background: #fafafa;
//box-shadow: 6px 0 6px -4px #ccc;
}
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-header .zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
//transition: box-shadow 0.3s ease;
}
.scroll-left-fixed{
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px #ccc;
}
}
.odd{
background-color:rgba(249,249,249,0.6);
//height: 100%;
width: 100%;
}
.even{
background-color:white ;
//height: 100%;
width: 100%;
}
.zb-table-tbody {
.zb-stick-side{
position: sticky;
left: 0;
box-sizing: border-box;
background:white;
//box-shadow: 6px 0 6px -2px #ccc;
}
.odd{
background:#f9f9f9;
//height: 100%;
width: 100%;
}
.even{
background:white ;
//height: 100%;
width: 100%;
}
}
}
</style>

View File

@@ -0,0 +1,84 @@
{
"id": "zb-table",
"displayName": "zb-table多功能表格",
"version": "1.1.1",
"description": "表格组件 支持固定表头和首列、及固定多列表格自适应内容排序多选checkbox、可点击删除编辑功能、兼容多端",
"keywords": [
"table",
"表格",
"固定表头、固定首列、多列",
"排序",
"自适应列宽、多选checkbox"
],
"repository": "https://github.com/zouzhibin/zb-table.git",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "u"
},
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}

View File

@@ -0,0 +1,147 @@
## 介绍
基于uni-app开发的一个普通的表格组件功能有固定首列和表头、排序、操作按钮、已用于生产环境
## table 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |是否必须|
| ------ | ------ | ------ | ------ | ------ |------ |
| data | 显示的数据 | array |-- | -- |必须 |
| column | 显示的列数据 | array |-- | -- |必须 |
| stripe | 是否为斑马纹 table| boolean | - |false | 否 |
| fit | 列的宽度是否自撑开 | boolean |true,false | false |否 |
| show-header | 是否显示表头 | boolean |true,false | true |否 |
| border | 是否带有纵向边框 | boolean |true,false | true |否 |
## table 事件
| 参数 | 说明 | 类型 | 可选值 | 默认值 |是否必须|
| ------ | ------ | ------ | ------ | ------ |------ |
| 事件名自定义 | 取决于type类型为operation的 renders参数里面 func 的参数名 | Function |(row,index)=>{} | -- |否 |
| toggleRowSelection | 用于多选表格,切换某一行的选中状态,第一个参数代表选中状态,参数二代表选中的对象 | Function |(selected ,array)=>{} | -- |否 |
| toggleAllSelection | 用于多选表格,切换所有行的选中状态 ,第一个参数代表选中状态,参数二代表选中的对象| Function |(selected ,array)=>{} | -- |否 |
| rowClick | 单击某行 第一个参数代表选中对象参数二代表选中的index| Function |(row ,index)=>{} | -- |否 |
## data 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| checked | 是否被勾选 | boolean |true,false | 无 |
## column 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| name | 属性值 | string |-- | 无 |
| label | 显示的标题 | string |-- | 无 |
| width | 列的宽度 | number |-- | 100 |
| fixed | 列是否固定在左侧true 表示固定在左侧 | boolean |true,false | true |
| sorter | 排序 | boolean |true,false | false |
| emptyString | 当值为空的时候默认显示的值 | string | | -- |
| filters | 对象过滤的选项,对象格式,对象中的元素需要有 key 和 value 属性。 | Object | {key:value} | -- |
| align | 对齐方式 | String | left/center/right | left |
| type | 为 operation 的时候代表为操作按钮 | string | operation | -- |
| renders | type 为operation的时候 必传 | Array | {name:'名字',func:"父元素接收事件名",type:"按钮的类型",size:"大小"} | -- |
```
type 为 operation 的时候代表为操作按钮
renders 代表传入的按钮 Array =>[
{
name:'编辑',
type:'primary',代表按钮的类型
size:'mini',代表按钮的大小
func:'edit' // func 代表操作按钮点击的事件名字 父元素接收的事件 父元素 @edit
例如:// <zb-table @edit=""/>
}
]
```
## 示例
```
<zb-table
:show-header="true"
:columns="column"
:stripe="true"
:fit="false"
@toggleRowSelection="toggleRowSelection"
@toggleAllSelection="toggleAllSelection"
:border="true"
@edit="buttonEdit"
@dele="dele"
:data="data"></zb-table>
```
## 数据格式
```
column:[
{ type:'selection', fixed:true,width:50 },
{ name: 'name', label: '姓名',fixed:false,width:80,emptyString:'--' },
{ name: 'age', label: '年纪',sorter:false,align:'right', },
{ name: 'sex', label: '性别',filters:{0:'男',1:'女'}},
{ name: 'address', label: '地址' },
{ name: 'date', label: '日期',sorter:true },
{ name: 'province', label: '省份' },
{ name: 'city', label: '城市' },
{ name: 'zip', label: '邮编' },
{ name: 'operation', type:'operation',label: '操作',renders:[
{
name:'编辑',
func:'edit' // func 代表子元素点击的事件 父元素接收的事件 父元素 @edit
},
{
name:'删除',
type:'warn',
func:"dele"
},
]},
],
data:[
{
date: '2016-05-02',
name: '王小虎1',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎2',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎3',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎4',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎5',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
}
]
```