1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
| /**
| * CInfiniteScroll
| * @author Tevin
| */
|
| <template>
| <scroll-view
| class="c-infinite-scroll"
| :scrollY="true"
| @scroll="evt=>onScroll(evt)"
| >
| <slot />
| <view class="c-infinite-bottom">
| <view
| class="c-infinite-loading"
| v-if="loading"
| >加载中,请稍后...</view>
| <view v-if="ending">
| <text
| class="c-infinite-ended"
| v-if="pageTotal > 0"
| >-- 没有更多了 --</text>
| <text
| class="c-infinite-empty"
| v-else
| >暂无数据...</text>
| </view>
| </view>
| </scroll-view>
| </template>
|
| <script>
| import { AtActivityIndicator } from 'taro-ui-vue';
| import './cInfiniteScroll.scss';
|
| export default {
| name: 'CInfiniteScroll',
| components: {
| AtActivityIndicator,
| },
| props: {
| autoInit: {
| type: Boolean,
| default: false,
| },
| onLoadMore: Function,
| },
| data() {
| return {
| inital: false,
| current: 0,
| pageTotal: 1,
| loading: false,
| ending: false,
| lastScrollTop: 0,
| scrollTimer: 0,
| };
| },
| methods: {
| hanldeLoadMore() {
| // 结束后跳过
| if (this.ending) {
| return;
| }
| // 加载中跳过
| if (this.loading) {
| return;
| }
| // 开始加载
| this.inital = true;
| this.loading = true;
| this.onLoadMore({
| current: this.current,
| next: this.current + 1,
| // 加载成功
| success: (options) => {
| setTimeout(() => {
| this.loading = false;
| // 没有数据
| if (!options.pageTotal || options.pageTotal <= 0) {
| this.ending = true;
| }
| // 有数据
| else {
| this.pageTotal = options.pageTotal;
| this.current = this.current + 1;
| // 已到最后一页
| if (this.current >= this.pageTotal) {
| this.ending = true;
| }
| }
| }, 100);
| },
| // 加载失败
| fail: () => {
| this.loading = false;
| },
| });
| },
| onScroll(evt) {
| // 往上
| if (this.lastScrollTop >= evt.detail.scrollTop) {
| this.lastScrollTop = evt.detail.scrollTop;
| return;
| }
| // 往下
| else {
| const viewHeight = evt.target.offsetHeight;
| const { scrollTop, scrollHeight } = evt.detail;
| // 阀值 100 像素,向下滚动到最后 100 像素,识别为启动加载
| if (viewHeight + scrollTop >= scrollHeight - 100) {
| clearTimeout(this.scrollTimer);
| this.scrollTimer = setTimeout(() => {
| this.hanldeLoadMore();
| }, 200);
| }
| }
| },
| initScroll() {
| // 已初始化,跳过
| if (this.inital) {
| return;
| }
| this.hanldeLoadMore();
| },
| },
| mounted() {
| // 开启自动初始化
| if (this.autoInit) {
| this.hanldeLoadMore();
| }
| },
| };
| </script>
|
|