Skip to content

Commit

Permalink
Merge pull request #3 from WeBankFinTech/dev-0.9.0
Browse files Browse the repository at this point in the history
Dev 0.9.0
  • Loading branch information
det101 authored Jun 22, 2020
2 parents 97dd526 + a803909 commit 5994c6f
Show file tree
Hide file tree
Showing 36 changed files with 1,604 additions and 14 deletions.
2 changes: 1 addition & 1 deletion web/src/js/component/table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
*/

import WeTable from './table.vue';
import WeTable from './resultTable/table.vue';
import historyTable from './historyTable/historyTable.vue';

export default { WeTable,
Expand Down
285 changes: 285 additions & 0 deletions web/src/js/component/table/resultTable/body.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
<template>
<div>
<div class="list-view-phantom" :style="{
width: contentWidth + 'px'
}">
</div>
<div ref="content" class="list-view-content" :class="{ header:type === 'header' }">
<div class="list-view-item" :style="{
width: sizeAndOffsetCahce[startIndex + index].size + 'px'
}" v-for="(col, index) in visibleData" :key="index">
<slot :col="col" :index="index"></slot>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
cache: {
type: Object,
default: () => {
return {};
},
},
isListenScroll: {
type: Boolean,
default: false,
},
data: {
type: Array,
required: true,
},

estimatedItemSize: {
type: Number,
default: 30,
},

itemSizeGetter: {
type: Function,
},
header: {
type: Array,
default: () => [],
},
type: String,
},

data() {
return {
viewWidth: 0,
lastMeasuredIndex: -1,
startIndex: 0,
sizeAndOffsetCahce: {},
visibleData: [],
ops: {
bar: {
background: 'rgb(24, 144, 255)',
keepShow: true,
minSize: 0.1,
},
rail: {
border: '1px solid #cecece',
size: '20px',
},
scrollButton: {
enable: true,
background: '#cecece',
},
},
cacheVH: {
v: {},
h: {
scrollLeft: 0,
},
},
isDivideWidth: false,
divideWidth: 0,
};
},
computed: {
contentWidth() {
const {
data,
lastMeasuredIndex,
estimatedItemSize
} = this;
let itemCount = data.length;
if (lastMeasuredIndex >= 0) {
const lastMeasuredSizeAndOffset = this.getLastMeasuredSizeAndOffset();
return lastMeasuredSizeAndOffset.offset + lastMeasuredSizeAndOffset.size + (itemCount - 1 -
lastMeasuredIndex) * estimatedItemSize;
} else {
return itemCount * estimatedItemSize;
}
},
},
watch: {
data: {
handler() {
this.resize();
},
deep: true,
},
},
mounted() {
this.setItemWidth();
},
methods: {
setItemWidth(isDataChange) {
this.viewWidth = this.$refs.content.clientWidth;
let count = 0;
this.header.forEach((item, index) => {
count += this.getItemSizeAndOffset(this.startIndex + index).size;
});
// 如果所有已分配宽度的列宽度和小于表格的宽度,就使用等比宽度
if (count && count <= this.viewWidth) {
this.isDivideWidth = true;
this.divideWidth = this.viewWidth / this.header.length;
let offset = 0;
for (const i in this.sizeAndOffsetCahce) {
if (this.sizeAndOffsetCahce.hasOwnProperty(i)) {
this.sizeAndOffsetCahce[i] = {
size: this.divideWidth,
offset,
};
this.cache[i] = this.divideWidth;
offset += this.divideWidth;
}
}
}
if (isDataChange) {
let {
v,
h
} = this.cacheVH;
this.handleScroll(v, h);
} else {
this.updateVisibleData();
}
},
getItemSizeAndOffset(index) {
const {
lastMeasuredIndex,
sizeAndOffsetCahce,
data,
itemSizeGetter,
header
} = this;
if (lastMeasuredIndex >= index) {
return sizeAndOffsetCahce[index];
}
let offset = 0;
if (lastMeasuredIndex >= 0) {
const lastMeasured = sizeAndOffsetCahce[lastMeasuredIndex];
if (lastMeasured) {
offset = lastMeasured.offset + lastMeasured.size;
}
}
for (let i = lastMeasuredIndex + 1; i <= index; i++) {
let item = header[i];
let size;
if (this.isDivideWidth) {
size = this.divideWidth;
this.cache[i] = size;
} else {
if (this.cache[i]) {
size = this.cache[i];
} else {
size = itemSizeGetter.call(null, item, i);
this.cache[i] = size;
}
}
sizeAndOffsetCahce[i] = {
size,
offset,
};
offset += size;
}
if (index > lastMeasuredIndex) {
this.lastMeasuredIndex = index;
}
return sizeAndOffsetCahce[index];
},

getLastMeasuredSizeAndOffset() {
return this.lastMeasuredIndex >= 0 ? this.sizeAndOffsetCahce[this.lastMeasuredIndex] : {
offset: 0,
size: 0
};
},

findNearestItemIndex(scrollLeft) {
const {
data
} = this;
let total = 0;
for (let i = 0, j = data.length; i < j; i++) {
const size = this.getItemSizeAndOffset(i).size;
total += size;
if (total >= scrollLeft || i === j - 1) {
return i;
}
}

return 0;
},

updateVisibleData(scrollLeft) {
let canScrollWidth = this.contentWidth - this.viewWidth;
scrollLeft = scrollLeft || 0;
if (scrollLeft > canScrollWidth) {
scrollLeft = canScrollWidth;
}
const start = this.findNearestItemIndex(scrollLeft);
const end = this.findNearestItemIndex(scrollLeft + (this.$el.clientWidth || 1400));
this.visibleData = this.data.slice(start, Math.min(end + 3, this.data.length));
this.startIndex = start;
this.$refs.content.style.webkitTransform = `translate3d(${this.getItemSizeAndOffset(start).offset}px, 0, 0)`;
},

handleScroll(v, h) {
const {
scrollLeft
} = h;
this.cacheVH = {
v,
h
};
this.$emit('on-scroll', {
v,
h
});
this.updateVisibleData(scrollLeft);
},

resize() {
this.reset();
this.setItemWidth(true);
},

reset() {
this.viewWidth = 0;
this.lastMeasuredIndex = -1;
this.startIndex = 0;
this.sizeAndOffsetCahce = {};
this.visibleData = [];
this.isDivideWidth = false;
this.divideWidth = 0;
},
},
beforeDestroy(){

}
};

</script>
<style>
.list-view-phantom {
position: absolute;
left: 0;
top: 0;
right: 0;
z-index: -1;
height: 100%;
}

.list-view-content {
display: flex;
left: 0;
right: 0;
top: 0;
position: absolute;
height: 100%;
}

.list-view-item {
height: 100%;
color: #666;
box-sizing: border-box;
flex-shrink: 0;
text-align: center;
}

</style>
Loading

0 comments on commit 5994c6f

Please sign in to comment.