Showing
1 changed file
with
0 additions
and
215 deletions
1 | -<template> | ||
2 | - <div ref="scroll" class="aaa"> | ||
3 | - <div ref="listBlock" | ||
4 | - :scroll-events="['scroll', 'scroll-end', 'before-scroll-start']" | ||
5 | - @scroll="onScrollHandle" | ||
6 | - @scroll-end="onScrollEndHandle" | ||
7 | - @before-scroll-start="beforeScrollStartHandle" | ||
8 | - v-bind="$attrs" v-on="$listeners"> | ||
9 | - | ||
10 | - <div class="infinite-list-block" :class="{'list-scroll': scrolling}"> | ||
11 | - <div class="infinite-list-chunk" | ||
12 | - v-for="(chunk, chunkIndex) in visibleList" | ||
13 | - :key="chunkIndex" | ||
14 | - :data-chunk-id="chunkIndex" | ||
15 | - :style="`${chunk.hide ? 'height:' + chunk.height + 'px' : ''}`"> | ||
16 | - <template v-if="!chunk.hide"> | ||
17 | - <div class="infinite-list-item" | ||
18 | - v-for="(item, index) in chunk.chunkList" | ||
19 | - :key="`${chunkIndex}-${index}`"> | ||
20 | - <slot name="item" :data="item"></slot> | ||
21 | - </div> | ||
22 | - </template> | ||
23 | - </div> | ||
24 | - </div> | ||
25 | - <div class="list-footer"> | ||
26 | - <Loading v-show="!noMore" class="load-icon" :size="20"></Loading> | ||
27 | - <p v-show="noMore" class="list-nomore"> | ||
28 | - 没有更多了 | ||
29 | - </p> | ||
30 | - </div> | ||
31 | - </div> | ||
32 | - </div> | ||
33 | -</template> | ||
34 | - | ||
35 | -<script> | ||
36 | -import {Scroll, Loading} from 'cube-ui'; | ||
37 | -import {chunk, takeRight, forEach} from 'lodash'; | ||
38 | - | ||
39 | -export default { | ||
40 | - name: 'InfiniteList', | ||
41 | - data() { | ||
42 | - return { | ||
43 | - scrolling: false, | ||
44 | - list: [], | ||
45 | - visibleList: [], | ||
46 | - chunkSize: 10, | ||
47 | - currentIndex: 0, | ||
48 | - startOffset: 0, | ||
49 | - noMore: false | ||
50 | - }; | ||
51 | - }, | ||
52 | - props: { | ||
53 | - offset: { | ||
54 | - type: Number, | ||
55 | - default: 100 | ||
56 | - }, | ||
57 | - onFetch: { | ||
58 | - type: Function, | ||
59 | - required: true | ||
60 | - }, | ||
61 | - thumbs: { | ||
62 | - type: Array, | ||
63 | - default() { | ||
64 | - return []; | ||
65 | - } | ||
66 | - } | ||
67 | - }, | ||
68 | - watch: { | ||
69 | - list(newV, oldV) { | ||
70 | - let index = oldV.length; | ||
71 | - | ||
72 | - if (newV.length <= index) { | ||
73 | - index = 0; | ||
74 | - } | ||
75 | - | ||
76 | - this.updateList(index); | ||
77 | - } | ||
78 | - }, | ||
79 | - mounted() { | ||
80 | - this.scrollHeight = this.$el.offsetHeight; | ||
81 | - this.$refs.scroll.onscroll = () => { | ||
82 | - console.log(this.$refs.scroll.scrollTop); | ||
83 | - console.log(this.$refs.listBlock.scrollTop); | ||
84 | - }; | ||
85 | - this.getData(); | ||
86 | - this.updateList(); | ||
87 | - }, | ||
88 | - methods: { | ||
89 | - updateList(index) { | ||
90 | - let list = this.visibleList; | ||
91 | - | ||
92 | - if (!Number(index)) { | ||
93 | - index = 0; | ||
94 | - list = []; | ||
95 | - } | ||
96 | - | ||
97 | - let chunks = []; | ||
98 | - | ||
99 | - if (this.list.length) { | ||
100 | - chunk(takeRight(this.list, this.list.length - index), this.chunkSize).forEach(val => { | ||
101 | - chunks.push({ | ||
102 | - chunkList: val | ||
103 | - }); | ||
104 | - }); | ||
105 | - } | ||
106 | - | ||
107 | - this.visibleList = list.concat(chunks); | ||
108 | - | ||
109 | - setTimeout(() => { | ||
110 | - // this.$refs.scroll.refresh(); | ||
111 | - }, 100); | ||
112 | - }, | ||
113 | - getData() { | ||
114 | - this.onFetch().then((res) => { | ||
115 | - if (!res) { | ||
116 | - this.noMore = true; | ||
117 | - } else { | ||
118 | - this.list = this.list.concat(res); | ||
119 | - } | ||
120 | - }); | ||
121 | - }, | ||
122 | - onScrollHandle() { | ||
123 | - | ||
124 | - }, | ||
125 | - onScrollEndHandle(scroll) { | ||
126 | - if (1000 - scroll.y > this.$refs.listBlock.offsetHeight) { | ||
127 | - this._timer && clearTimeout(this._timer); | ||
128 | - this._timer = setTimeout(() => { | ||
129 | - this.getData(); | ||
130 | - }, 50); | ||
131 | - } | ||
132 | - | ||
133 | - this.clacViewChunks(-scroll.y) | ||
134 | - this.scrolling = false; | ||
135 | - }, | ||
136 | - beforeScrollStartHandle() { | ||
137 | - this.scrolling = true; | ||
138 | - }, | ||
139 | - clacViewChunks(top) { | ||
140 | - if (this.list.length < 50) { | ||
141 | - return; | ||
142 | - } | ||
143 | - // | ||
144 | - | ||
145 | - let time = new Date(); | ||
146 | - | ||
147 | - let $children = this.$refs.listBlock.children; | ||
148 | - let height = 0; | ||
149 | - let hasChange = false; | ||
150 | - | ||
151 | - forEach($children, (dom, index) => { | ||
152 | - let chunk = this.visibleList[index]; | ||
153 | - let hide = false; | ||
154 | - let h = dom.offsetHeight; | ||
155 | - | ||
156 | - if (height > top + this.scrollHeight * 5 || height + h < top - this.scrollHeight * 4) { | ||
157 | - hide = true; | ||
158 | - } | ||
159 | - | ||
160 | - if (!!chunk.hide !== hide) { | ||
161 | - hasChange = true; | ||
162 | - chunk.hide = hide; | ||
163 | - chunk.height = h; | ||
164 | - } | ||
165 | - | ||
166 | - height += h; | ||
167 | - }); | ||
168 | - | ||
169 | - if (hasChange) { | ||
170 | - time = new Date(); | ||
171 | - this.visibleList = [...this.visibleList]; | ||
172 | - // this.$nextTick(() => { | ||
173 | - // alert(new Date() - time); | ||
174 | - // }); | ||
175 | - } | ||
176 | - | ||
177 | - console.log(hasChange); | ||
178 | - } | ||
179 | - }, | ||
180 | - components: { | ||
181 | - Scroll, | ||
182 | - Loading | ||
183 | - } | ||
184 | -}; | ||
185 | -</script> | ||
186 | - | ||
187 | -<style lang="scss"> | ||
188 | - .aaa { | ||
189 | - height: 100%; | ||
190 | - overflow: scroll; | ||
191 | - } | ||
192 | - | ||
193 | - .list-scroll { | ||
194 | - position: relative; | ||
195 | - | ||
196 | - &:after { | ||
197 | - content: ''; | ||
198 | - position: absolute; | ||
199 | - left: 0; | ||
200 | - right: 0; | ||
201 | - top: 0; | ||
202 | - bottom: 0; | ||
203 | - z-index: 1; | ||
204 | - } | ||
205 | - } | ||
206 | - | ||
207 | - .list-footer { | ||
208 | - text-align: center; | ||
209 | - padding: 20px; | ||
210 | - | ||
211 | - > * { | ||
212 | - display: inline-block; | ||
213 | - } | ||
214 | - } | ||
215 | -</style> |
-
Please register or login to post a comment