表格组件
<template>
<div
class="sticky-table"
:style="{ height: tableHeight > 0 ? tableHeight + 'rem' : 'auto' }"
:class="{ tabletype: tableType == '产品' }"
@touchstart="touchstart"
@touchmove="touchmove"
@touchend="touchend"
>
<van-list
finished-text="没有更多了"
:finished="finished"
:offset="300"
@load="onLoad"
>
<table cellspacing="0" border="0" cellpadding="0">
<thead>
<tr>
<th v-for="(item, index) in tableHeader" :key="index">
{{ item.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in dataSheet" :key="index">
<td v-for="(context, i) in tableHeader" :key="i">
<!--金额-->
<p v-if="context.prop.includes('Cash')" class="td-p">
¥{{ item[context.prop] ? item[context.prop] : '--' }}
</p>
<p v-else class="td-p">
{{ item[context.prop] ? item[context.prop] : '--' }}
</p>
<!--tableType == '产品'-->
<div v-if="false" class="td-hint">
<!--总商户数-->
<div
v-if="context.prop == 'totalShopQuantity_format'"
class="td-hint-lastmonth"
>
上月:{{ item.totalShopQuantityLastMonth_format }}
</div>
<!--有效商户数-->
<div
v-if="context.prop == 'availableShopQuantity_format'"
class="td-hint-sjicon"
>
<!--增加-->
<div
v-if="item.availableShopAdd"
class="add"
:style="{
color:
parseInt(item.availableShopCalc) > 0
? '#07c160'
: '#999999'
}"
>
<em class="iconfont icon-jiantou_xiangshang_o"></em
>{{ item.availableShopCalc }}
</div>
<!--下降-->
<div
v-else
class="reduce"
:style="{
color:
parseInt(item.availableShopCalc) > 0
? '#de3a3f'
: '#999999'
}"
>
<em class="iconfont icon-jiantou_xiangxia_o"></em
>{{ item.availableShopCalc }}
</div>
</div>
<!--月活跃商户数-->
<div
v-if="context.prop == 'monthActiveShopQuantity_format'"
class="td-hint-sjicon"
>
<!--增加-->
<div
v-if="item.monthActiveShopAdd"
class="add"
:style="{
color:
parseInt(item.monthActiveShopCalc) > 0
? '#07c160'
: '#999999'
}"
>
<em class="iconfont icon-jiantou_xiangshang_o"></em
>{{ item.monthActiveShopCalc }}
</div>
<!--下降-->
<div
v-else
class="reduce"
:style="{
color:
parseInt(item.monthActiveShopCalc) > 0
? '#de3a3f'
: '#999999'
}"
>
<em class="iconfont icon-jiantou_xiangxia_o"></em
>{{ item.monthActiveShopCalc }}
</div>
</div>
<!--月新增商户数-->
<div
v-if="context.prop == 'monthNewMemberQuantity_format'"
class="td-hint-sjicon"
>
<p class="lastmonth-add">
上月新增:<span
:style="{
color:
parseInt(item.monthNewShopCalc) > 0
? '#07c160'
: '#999999'
}"
>{{ item.monthNewShopCalc }}</span
>
</p>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</van-list>
<div class="hint" v-if="finishedText">{{ finishedText }}</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'
@Component({})
export default class ScrollTable extends Vue {
@Prop({ default: {} }) tableHeader!: any
@Prop({ default: {} }) dataSheet!: any
@Prop({ default: 10 }) tableHeight!: number
@Prop({ default: '' }) finishedText!: string
@Prop({ default: '' }) tableType!: string
@Prop({ default: true }) upDownScroll!: string // 是否需要重写滑动效果的
finished: boolean = false
touchX: number = 0
touchY: number = 0
onLoad() {
this.$emit('loadMore')
}
// 自定义滑动
touchstart(event: any) {
if (!this.upDownScroll) return
event.preventDefault()
this.touchX = event.changedTouches[0].clientX
this.touchY = event.changedTouches[0].clientY
}
touchmove(event: any) {
if (!this.upDownScroll) return
let element: any = document.querySelector('.sticky-table')
event.preventDefault()
// 计算手指偏移量
const offsetX = event.changedTouches[0].clientX - this.touchX
const offsetY = event.changedTouches[0].clientY - this.touchY
element.scrollLeft = element.scrollLeft - offsetX
element.scrollTop = element.scrollTop - offsetY
this.touchX = event.changedTouches[0].clientX
this.touchY = event.changedTouches[0].clientY
}
touchend(event: any) {
if (!this.upDownScroll) return
event.preventDefault()
this.touchX = event.changedTouches[0].clientX
this.touchY = event.changedTouches[0].clientY
}
}
</script>
<style lang="less" scoped>
@import '../../../../assets/css/variable.less';
.sticky-table {
overflow-x: scroll;
overflow-y: scroll;
width: 100%;
height: 320px; /* 固定高度 */
/*border: 1px solid @dataTableBorderColor;*/
border-bottom: 0;
-webkit-overflow-scrolling: touch;
table {
border-collapse: separate;
table-layout: fixed;
width: 100%; /* 固定寬度 */
}
td,
th {
border-right: 1px solid @dataTableBorderColor;
border-bottom: 1px solid @dataTableBorderColor;
width: 100px;
height: 30px;
font-weight: normal;
padding: 5px;
word-wrap: break-word;
white-space: normal;
word-break: break-all;
}
th {
background-color: @dataTableBg;
border-top: 1px solid @dataTableBorderColor;
}
thead tr th {
position: sticky;
top: 0; /* 第一列最上 */
}
td:first-child,
th:first-child {
position: sticky;
left: 0; /* 首行在左 */
z-index: 1;
background-color: @dataTableBg;
}
td:first-child {
border-left: 1px solid @dataTableBorderColor;
}
th:first-child {
z-index: 2;
border-left: 1px solid @dataTableBorderColor;
}
.hint {
padding: 10px;
text-align: center;
color: #999999;
}
.td-hint {
&-lastmonth {
margin-top: 3px;
color: #999999;
}
&-sjicon {
margin-top: 3px;
.add {
color: #07c160;
}
.reduce {
color: @datathemeColor;
}
.lastmonth-add {
color: #999999;
}
}
}
}
.tabletype {
tbody {
tr {
td {
text-align: right;
&:first-child {
text-align: left;
}
}
}
}
}
</style>
使用页面:
在使用页面禁止掉自带的滑动
mounted() {
let u = navigator.userAgent
if (u.indexOf('iPhone') > -1) { // ios才禁止
let element: any = document.querySelector('#agentInfo') // 禁止页面的dom
element.addEventListener(
'touchmove',
function (e: any) {
e.preventDefault() // 阻止默认的处理方式(阻止下拉滑动的效果)
},
{ passive: false }
) // passive 参数不能省略,用来兼容ios和android
}
}