1
0
mirror of https://github.com/ialley-workshop-open/uni-halo.git synced 2026-06-11 12:49:30 +08:00
Files
uni-halo/tm-vuetify/components/tm-table/tm-table.vue
T
2022-12-06 15:08:29 +08:00

292 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="tm-table" >
<scroll-view v-if="fixedHeader" :scroll-with-animation="true" :scroll-left="scrollx_px_header" @scroll="scrollChange($event,'header')" scroll-x="" class="tm-table-scroll tm-table-scroll-body fulled">
<view class=" tm-table-scroll-header">
<tm-row v-if="listdata.header.length>0" preatClass="tm-table-header " style="white-space: nowrap;">
<block v-for="(item,index) in listdata.header" :key="index">
<tm-col :maxCol="maxGrid" :grid="item['grid']?item.grid:col"
:color="(listdata.headerBgcolor?listdata.headerBgcolor:item.color)+ (black_tmeme?' bk ':'')"
custom-class="" :padding="5">
<view @click="rank(index)" class="text-size-s vertical-align-middle text-weight-b text-overflow-1 flex-center"
style="white-space: initial;height: 36px;">
<view class="flex-center vertical-align-middle fulled-height">
<text>{{item[rangKey]}}</text>
<view v-if="item['sort']" class="flex-col flex-center pl-10 flex-shrink" style="line-height: 0;">
<text :class="[index==rank_index&&rank_type==0?'':'opacity-6']" class="iconfont icon-sort-up text-size-xs "></text>
<text :class="[index==rank_index&&rank_type==1?'':'opacity-6']" class="iconfont icon-sort-down text-size-xs mt-14"></text>
</view>
</view>
</view>
</tm-col>
</block>
</tm-row>
</view>
</scroll-view>
<scroll-view :scroll-with-animation="true" :scroll-left="scrollx_px_body" @scroll="scrollChange($event,'body')" scroll-x :scroll-y="height_s?true:false" class="tm-table-scroll tm-table-scroll-body fulled"
:style="{
height:height_s?`${height_s}px`:'auto'
}">
<view v-if="!fixedHeader" class=" tm-table-scroll-header">
<tm-row v-if="listdata.header.length>0" preatClass="tm-table-header " style="white-space: nowrap;">
<block v-for="(item,index) in listdata.header" :key="index">
<tm-col :maxCol="maxGrid" :grid="item['grid']?item.grid:col"
:color="(listdata.headerBgcolor?listdata.headerBgcolor:item.color)+ (black_tmeme?' bk ':'')"
custom-class="" :padding="5">
<view @click="rank(index)" class="text-size-s vertical-align-middle text-weight-b text-overflow-1 flex-center"
style="white-space: initial;height: 36px;">
<view class="flex-center vertical-align-middle fulled-height">
<text>{{item[rangKey]}}</text>
<view v-if="item['sort']" class="flex-col flex-center pl-10 flex-shrink" style="line-height: 0;">
<text :class="[index==rank_index&&rank_type==0?'':'opacity-6']" class="iconfont icon-sort-up text-size-xs "></text>
<text :class="[index==rank_index&&rank_type==1?'':'opacity-6']" class="iconfont icon-sort-down text-size-xs mt-14"></text>
</view>
</view>
</view>
</tm-col>
</block>
</tm-row>
</view>
<block v-for="(item,index) in listdata.col" :key="index">
<tm-row v-if="listdata.col.length>0" preatClass="tm-table-header" style="white-space: nowrap;">
<block v-for="(item2,index2) in item" :key="index2">
<tm-col
:maxCol="maxGrid"
:grid="item2['grid']?item2['grid']:(listdata.header[index2]['grid']?listdata.header[index2]['grid']:col)"
:color="item2.color?item2.color:(listdata.header[index2].color?listdata.header[index2].color+' text':(item2.color?item2.color+' text':((index+1)%2?activeCellColorRow+' text':'white'))) + (black_tmeme?' bk ':'')">
<view @click="onclick(index,index2,item2)"
class="text-size-s border-grey-lighten-3-b-1 flex-center wrap fulled-height overflow"
:class="black_tmeme?' bk ':''"
:style="{height: `${rowHeight}rpx`}">
<view class=" overflow fulled fulled-height " :class="(item2['rowAlign']||listdata.header[index2]['rowAlign']||rowAlign)">
<slot name="cell" :data="{parentIndex:index,childrenIndex:index2,data:item2}">
<text class="pa-10">{{item2[rangKey]}}</text>
</slot>
</view>
</view>
</tm-col>
</block>
</tm-row>
</block>
</scroll-view>
</view>
</template>
<script>
/**
* 表格
* @property {Number} height = [] 默认:0,表格的整体高度,如果设定了高度,超过后变为滚动。
* @property {Number} col = [] 默认:0,默认的列宽,记住是1-12列
* @property {Boolean} fixedHeader = [] 默认:false,是否固定顶部表头
* @property {String} activeCellColorRow = [] 默认:blue,默认高亮的行颜色
* @property {String} rang-key = [] 默认:textlist对象时读取文本的字段,默认text
* @property {Number} rowHeight = [] 默认:72,单元格的高度。单位rpx
* @property {Array} rowAlign = [] 默认:'flex-center'
* 单元格对齐方式本库类,也可能通过单元格数据对齐覆盖此全局变量,以控制单个的对齐方式
* @property {Number} maxGrid = [] 默认:12,布局的列表,比如我想一行5个,就可以用到此属性,设置为10,然后grid=2即可。
* @property {String} sort-key = [] 默认:text,默认text即rangKey字段进行排序。排序的字段名称。
* @property {Object} list = [] 默认:{}list数据格式见文档
* @example <tm-table :list="list2"></tm-table>
*/
import tmRow from "@/tm-vuetify/components/tm-row/tm-row.vue"
import tmCol from "@/tm-vuetify/components/tm-col/tm-col.vue"
import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
export default {
components: {
tmRow,
tmCol,
tmIcons
},
name: "tm-table",
props: {
height: {
type: Number,
default: 0
},
black: {
type: Boolean | String,
default: null
},
// 默认的列宽
col: {
type: Number,
default: 3
},
// 默认高亮的单元格。
activeCellColorRow: {
type: String,
default: 'primary'
},
// 对象时读取文本的字段,默认text
rangKey: {
type: String,
default: 'text'
},
sortKey:{
type:String,
default:'text'
},
list: {
type: Object,
default: () => {
return {};
}
},
//默认计算方式是12列布局。
maxGrid:{
type:Number,
default:12
},
fixedHeader:{
type:Boolean|String,
default:false,
},
rowHeight:{
type:Number,
default:72
},
rowAlign:{
type:String,
default:'flex-center'
}
},
data() {
return {
scrollx_px_header: 0,
scrollx_px_body: 0,
scrollx_obj: null,
orderlist: null,
rank_index:null,
rank_type:2,
list_default: {
header: [], //头部数据
col: [], //行的数据
headerBgcolor: 'primary', //头部的背景颜色
}
};
},
created() {
this.listdata = this.list;
},
watch:{
list:{
deep:true,
handler(){
this.listdata = this.list;
}
}
},
computed: {
black_tmeme: function() {
if (this.black !== null) return this.black;
return this.$tm.vx.state().tmVuetify.black;
},
listdata: {
get: function() {
return this.orderlist||this.list_default;
},
set: function(val) {
let list = {
...this.list_default,
...val
};
this.orderlist = uni.$tm.deepClone(list);
}
},
height_s: function() {
return uni.upx2px(this.height);
}
},
methods: {
rank(index, type) {
if(!this.listdata.header[index]['sort']){
return;
}
let t = this;
let list = uni.$tm.deepClone(this.listdata);
this.rank_index = index;
if(this.rank_type==0){
let str = this.listdata.col[0][index][t.rangKey]
if(/^[0-9]+(.[0-9]{0,})?$/g.test(str)){
list.col.sort((a,b)=>b[index][t.sortKey]-a[index][t.sortKey])
this.rank_type = 1
}else{
list = this.list
this.rank_type = 2
}
this.listdata = list;
return;
}else if(this.rank_type==1){
this.listdata = this.list;
this.rank_type = 2
return;
}else{
this.rank_type = 0
let str = this.listdata.col[0][index][t.rangKey]
if(/^[0-9]+(.[0-9]{0,})?$/g.test(str)){
list.col.sort((a,b)=>a[index][t.sortKey]-b[index][t.sortKey])
}else{
list.col.reverse()
}
this.listdata = list;
return;
}
},
scrollChange(e,type){
if(type=='header'){
this.scrollx_px_body = e.detail.scrollLeft
}else if(type=="body"){
this.scrollx_px_header = e.detail.scrollLeft
}
},
onclick(index, index2, item) {
this.$emit("click", {
row: index,
col: index2,
data: item
})
}
}
}
</script>
<style lang="less" scoped>
.tm-table {
.tm-table-scroll-header {
position: relative;
z-index: 2;
.tm-header-body {}
}
.tm-table-scroll-body {
position: relative;
z-index: 1;
}
}
.tm-table-header {
flex-flow: nowrap !important;
white-space: nowrap !important;
display: flex;
flex-flow: row nowrap;
.tm-col {
flex-shrink: 0;
height: 100%;
}
}
</style>