Skip to content

Commit 6091b11

Browse files
author
yuchenyao
authored
Merge pull request #1 from WeBankFinTech/dev-0.9.0
Dev 0.9.0
2 parents d7e3d60 + 4d9c99d commit 6091b11

File tree

36 files changed

+1604
-14
lines changed

36 files changed

+1604
-14
lines changed

web/src/js/component/table/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*/
1717

18-
import WeTable from './table.vue';
18+
import WeTable from './resultTable/table.vue';
1919
import historyTable from './historyTable/historyTable.vue';
2020

2121
export default { WeTable,
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
<template>
2+
<div>
3+
<div class="list-view-phantom" :style="{
4+
width: contentWidth + 'px'
5+
}">
6+
</div>
7+
<div ref="content" class="list-view-content" :class="{ header:type === 'header' }">
8+
<div class="list-view-item" :style="{
9+
width: sizeAndOffsetCahce[startIndex + index].size + 'px'
10+
}" v-for="(col, index) in visibleData" :key="index">
11+
<slot :col="col" :index="index"></slot>
12+
</div>
13+
</div>
14+
</div>
15+
</template>
16+
<script>
17+
export default {
18+
props: {
19+
cache: {
20+
type: Object,
21+
default: () => {
22+
return {};
23+
},
24+
},
25+
isListenScroll: {
26+
type: Boolean,
27+
default: false,
28+
},
29+
data: {
30+
type: Array,
31+
required: true,
32+
},
33+
34+
estimatedItemSize: {
35+
type: Number,
36+
default: 30,
37+
},
38+
39+
itemSizeGetter: {
40+
type: Function,
41+
},
42+
header: {
43+
type: Array,
44+
default: () => [],
45+
},
46+
type: String,
47+
},
48+
49+
data() {
50+
return {
51+
viewWidth: 0,
52+
lastMeasuredIndex: -1,
53+
startIndex: 0,
54+
sizeAndOffsetCahce: {},
55+
visibleData: [],
56+
ops: {
57+
bar: {
58+
background: 'rgb(24, 144, 255)',
59+
keepShow: true,
60+
minSize: 0.1,
61+
},
62+
rail: {
63+
border: '1px solid #cecece',
64+
size: '20px',
65+
},
66+
scrollButton: {
67+
enable: true,
68+
background: '#cecece',
69+
},
70+
},
71+
cacheVH: {
72+
v: {},
73+
h: {
74+
scrollLeft: 0,
75+
},
76+
},
77+
isDivideWidth: false,
78+
divideWidth: 0,
79+
};
80+
},
81+
computed: {
82+
contentWidth() {
83+
const {
84+
data,
85+
lastMeasuredIndex,
86+
estimatedItemSize
87+
} = this;
88+
let itemCount = data.length;
89+
if (lastMeasuredIndex >= 0) {
90+
const lastMeasuredSizeAndOffset = this.getLastMeasuredSizeAndOffset();
91+
return lastMeasuredSizeAndOffset.offset + lastMeasuredSizeAndOffset.size + (itemCount - 1 -
92+
lastMeasuredIndex) * estimatedItemSize;
93+
} else {
94+
return itemCount * estimatedItemSize;
95+
}
96+
},
97+
},
98+
watch: {
99+
data: {
100+
handler() {
101+
this.resize();
102+
},
103+
deep: true,
104+
},
105+
},
106+
mounted() {
107+
this.setItemWidth();
108+
},
109+
methods: {
110+
setItemWidth(isDataChange) {
111+
this.viewWidth = this.$refs.content.clientWidth;
112+
let count = 0;
113+
this.header.forEach((item, index) => {
114+
count += this.getItemSizeAndOffset(this.startIndex + index).size;
115+
});
116+
// 如果所有已分配宽度的列宽度和小于表格的宽度,就使用等比宽度
117+
if (count && count <= this.viewWidth) {
118+
this.isDivideWidth = true;
119+
this.divideWidth = this.viewWidth / this.header.length;
120+
let offset = 0;
121+
for (const i in this.sizeAndOffsetCahce) {
122+
if (this.sizeAndOffsetCahce.hasOwnProperty(i)) {
123+
this.sizeAndOffsetCahce[i] = {
124+
size: this.divideWidth,
125+
offset,
126+
};
127+
this.cache[i] = this.divideWidth;
128+
offset += this.divideWidth;
129+
}
130+
}
131+
}
132+
if (isDataChange) {
133+
let {
134+
v,
135+
h
136+
} = this.cacheVH;
137+
this.handleScroll(v, h);
138+
} else {
139+
this.updateVisibleData();
140+
}
141+
},
142+
getItemSizeAndOffset(index) {
143+
const {
144+
lastMeasuredIndex,
145+
sizeAndOffsetCahce,
146+
data,
147+
itemSizeGetter,
148+
header
149+
} = this;
150+
if (lastMeasuredIndex >= index) {
151+
return sizeAndOffsetCahce[index];
152+
}
153+
let offset = 0;
154+
if (lastMeasuredIndex >= 0) {
155+
const lastMeasured = sizeAndOffsetCahce[lastMeasuredIndex];
156+
if (lastMeasured) {
157+
offset = lastMeasured.offset + lastMeasured.size;
158+
}
159+
}
160+
for (let i = lastMeasuredIndex + 1; i <= index; i++) {
161+
let item = header[i];
162+
let size;
163+
if (this.isDivideWidth) {
164+
size = this.divideWidth;
165+
this.cache[i] = size;
166+
} else {
167+
if (this.cache[i]) {
168+
size = this.cache[i];
169+
} else {
170+
size = itemSizeGetter.call(null, item, i);
171+
this.cache[i] = size;
172+
}
173+
}
174+
sizeAndOffsetCahce[i] = {
175+
size,
176+
offset,
177+
};
178+
offset += size;
179+
}
180+
if (index > lastMeasuredIndex) {
181+
this.lastMeasuredIndex = index;
182+
}
183+
return sizeAndOffsetCahce[index];
184+
},
185+
186+
getLastMeasuredSizeAndOffset() {
187+
return this.lastMeasuredIndex >= 0 ? this.sizeAndOffsetCahce[this.lastMeasuredIndex] : {
188+
offset: 0,
189+
size: 0
190+
};
191+
},
192+
193+
findNearestItemIndex(scrollLeft) {
194+
const {
195+
data
196+
} = this;
197+
let total = 0;
198+
for (let i = 0, j = data.length; i < j; i++) {
199+
const size = this.getItemSizeAndOffset(i).size;
200+
total += size;
201+
if (total >= scrollLeft || i === j - 1) {
202+
return i;
203+
}
204+
}
205+
206+
return 0;
207+
},
208+
209+
updateVisibleData(scrollLeft) {
210+
let canScrollWidth = this.contentWidth - this.viewWidth;
211+
scrollLeft = scrollLeft || 0;
212+
if (scrollLeft > canScrollWidth) {
213+
scrollLeft = canScrollWidth;
214+
}
215+
const start = this.findNearestItemIndex(scrollLeft);
216+
const end = this.findNearestItemIndex(scrollLeft + (this.$el.clientWidth || 1400));
217+
this.visibleData = this.data.slice(start, Math.min(end + 3, this.data.length));
218+
this.startIndex = start;
219+
this.$refs.content.style.webkitTransform = `translate3d(${this.getItemSizeAndOffset(start).offset}px, 0, 0)`;
220+
},
221+
222+
handleScroll(v, h) {
223+
const {
224+
scrollLeft
225+
} = h;
226+
this.cacheVH = {
227+
v,
228+
h
229+
};
230+
this.$emit('on-scroll', {
231+
v,
232+
h
233+
});
234+
this.updateVisibleData(scrollLeft);
235+
},
236+
237+
resize() {
238+
this.reset();
239+
this.setItemWidth(true);
240+
},
241+
242+
reset() {
243+
this.viewWidth = 0;
244+
this.lastMeasuredIndex = -1;
245+
this.startIndex = 0;
246+
this.sizeAndOffsetCahce = {};
247+
this.visibleData = [];
248+
this.isDivideWidth = false;
249+
this.divideWidth = 0;
250+
},
251+
},
252+
beforeDestroy(){
253+
254+
}
255+
};
256+
257+
</script>
258+
<style>
259+
.list-view-phantom {
260+
position: absolute;
261+
left: 0;
262+
top: 0;
263+
right: 0;
264+
z-index: -1;
265+
height: 100%;
266+
}
267+
268+
.list-view-content {
269+
display: flex;
270+
left: 0;
271+
right: 0;
272+
top: 0;
273+
position: absolute;
274+
height: 100%;
275+
}
276+
277+
.list-view-item {
278+
height: 100%;
279+
color: #666;
280+
box-sizing: border-box;
281+
flex-shrink: 0;
282+
text-align: center;
283+
}
284+
285+
</style>

0 commit comments

Comments
 (0)