layout-scroll.vue
2.67 KB
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
<template>
<div class="layout-scroll">
<div class="layout-scroll-main" ref="scroll">
<div class="scroll-body" :style="{'minHeight': wrapHeight + 'px'}">
<slot></slot>
</div>
<div v-if="loading && !loading.hide" class="loading">
<p v-if="loading.noMore" class="load-text">{{loading.noMoreText || '没有更多了'}}</p>
<Loading v-else :size="20"></Loading>
</div>
</div>
</div>
</template>
<script>
import {throttle} from 'lodash';
import {Loading} from 'cube-ui';
const EVENT_SCROLL = 'scroll';
export default {
name: 'LayoutScroll',
data() {
return {
noMore: false,
wrapHeight: 0,
};
},
props: {
loading: Object
},
mounted() {
this.wrapHeight = this.$el.offsetHeight;
this._forceUpdate = throttle(this.forceUpdate.bind(this), 500);
this._onPullingUp = throttle(this.onPullingUp.bind(this), 1000);
let supportsPassive = false;
try {
const opts = Object.defineProperty({}, 'passive', {
get() {
supportsPassive = true;
return true;
}
});
window.addEventListener('test', null, opts);
} catch (e) {} //eslint-disable-line
this.$el.addEventListener(EVENT_SCROLL, this.onScroll, supportsPassive ? { passive: true } : false);
},
beforeDestroy() {
this.$el.removeEventListener(EVENT_SCROLL, this.onScroll);
},
methods: {
scrollTo() {
let top = arguments[1] || arguments[0];
this.$el.scrollTop = Math.abs(top);
},
onScroll() {
let top = this.$el.scrollTop;
if (this.lastTop === top) {
return;
}
this._forceUpdate();
this.lastTop = top;
this.$emit('scroll', {y: -top});
this.scrollTimer && clearTimeout(this.scrollTimer);
this.scrollTimer = setTimeout(this.onScrollEnd.bind(this), 400);
if (!this.loading || !this.loading.noMore) {
if (this.scrollHeight - top < this.$el.offsetHeight * 2) {
this._onPullingUp();
}
}
},
getScrollTop() {
return this.$el.scrollTop;
},
onScrollEnd() {
this.$emit('scroll-end', {y: -this.$el.scrollTop});
},
onPullingUp() {
this.$emit('pulling-up');
},
forceUpdate() {
this.scrollHeight = this.$refs.scroll.offsetHeight;
}
},
components: {
Loading
}
};
</script>
<style lang="scss" scoped>
.layout-scroll {
height: 100%;
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
position: relative;
z-index: 0;
}
.layout-scroll-main {
min-height: 100%;
}
.loading {
padding: 20px 0;
line-height: 40px;
text-align: center;
/deep/ .cube-loading-spinners {
margin: auto;
}
}
</style>