下拉加载
父组件
<template>
<c-scroll
ref="cscroll"
@requestData="requestData"
>
<template slot="list">
<div v-for="item in list" :key="item" class="scroll-item">
{{item}}
</div>
</template>
</c-scroll>
</template>
<script>
import CScroll from "@/components/common/c-scroll";
export default {
components: {
CScroll
},
data() {
return {
list: [1,2,3,4,5,6,7,8,9, 10]
};
},
methods: {
requestData() {
this.$refs.cscroll.setLoading(true);
setTimeout(() => {
this.$refs.cscroll.setLoading(false);
if (this.list.length <= 10) {
this.list = this.list.concat([11,12,13,14,15,16,17,18,19,20]);
} else {
this.$refs.cscroll.setOverflow(true);
}
}, 3000);
}
}
};
</script>
<style lang="scss" scoped>
.scroll-item {
height: 200px;
margin-bottom: 10px;
}
</style>
子组件
<template>
<div
class="scroll-c"
@scroll="scrollFn"
>
<slot name="list"></slot>
<div
v-for="item in list"
:key="item"
class="scroll-item">{{item}}</div>
<van-loading v-if="loading" size="24px">加载中...</van-loading>
<c-van-divider
v-if="overflow"
:className="'hr-top'"
:text="`我是有底线的`"
/>
</div>
</template>
<script>
import VanLoading from "vant/lib/loading";
import "vant/lib/loading/style";
import CVanDivider from "@/components/common/c-hr/divider.vue";
import {debounce} from "@/lib/debounce";
export default {
components: {
VanLoading,
CVanDivider
},
data() {
this.scrollFnDebounce = debounce((top, offsetTop) => {
if (top > offsetTop) {
this.requestData();
}
});
return {
overflow: false,
loading: false,
list: []
};
},
methods: {
setLoading(bool) {
this.loading = bool;
},
setOverflow (bool) {
this.overflow = bool;
},
requestData() {
console.log("aaa");
this.$emit("requestData");
},
scrollFn(e) {
if (this.loading || this.overflow) {
return;
}
const scrollTop = e.currentTarget.scrollTop;
const clientHeight = e.currentTarget.clientHeight;
const children = e.currentTarget.querySelectorAll(".scroll-item");
if (children.length > 0) {
const lastDom = children[children.length - 1];
this.scrollFnDebounce(scrollTop + clientHeight, lastDom.offsetTop);
}
}
}
};
</script>
<style lang="scss" scoped>
.scroll-c {
height: 100%;
overflow-y: auto;
position: relative;
.scroll-item {
// height: 200px;
// margin-bottom: 10px;
position: relative;
}
::v-deep .van-loading {
text-align: center;
margin: 20px;
}
}
</style>
上拉加载,加载数据往前加的
父组件
<template>
<c-scroll
ref="cscroll"
@requestData="requestData"
>
<template slot="list">
<div v-for="item in list" :key="item" class="scroll-item">
{{item}}
</div>
</template>
</c-scroll>
</template>
<script>
import CScroll from "@/components/common/c-scroll";
export default {
components: {
CScroll
},
data() {
return {
list: [1,2,3,4,5,6,7,8,9, 10]
};
},
mounted() {
this.$nextTick(() => {
if (this.$refs.cscroll) {
const scrollHeight = this.$refs.cscroll.getScrollHeight();
console.log(scrollHeight, "scrollHeight");
this.$refs.cscroll.scrollYTo(scrollHeight);
}
});
},
methods: {
requestData() {
this.$refs.cscroll.setLoading(true);
setTimeout(() => {
this.$refs.cscroll.setLoading(false);
if (this.list.length <= 10) {
const list = [11,12,13,14,15,16,17,18,19,20];
list.forEach(item => {
this.list.unshift(item);
});
this.$nextTick(() => {
this.$refs.cscroll.scrollYTo(list.length * 200 - 40);
});
} else {
this.$refs.cscroll.setOverflow(true);
}
}, 3000);
}
}
};
</script>
<style lang="scss" scoped>
.scroll-item {
height: 200px;
margin-bottom: 10px;
}
</style>
子组件
<template>
<div
ref="scrollC"
class="scroll-c"
@scroll="scrollFn"
>
<div class="loading-top-c">
<van-loading v-if="loading" size="24px">加载中...</van-loading>
</div>
<slot name="list"></slot>
<div
v-for="item in list"
:key="item"
class="scroll-item">{{item}}</div>
</div>
</template>
<script>
import VanLoading from "vant/lib/loading";
import "vant/lib/loading/style";
import {debounce} from "@/lib/debounce";
export default {
components: {
VanLoading,
},
data() {
this.scrollFnDebounce = debounce((Num, scrollTop) => {
console.log(Num, scrollTop, "scrollTop");
if (scrollTop < Num) {
this.requestData();
}
});
return {
overflow: false,
loading: false,
list: []
};
},
methods: {
setLoading(bool) {
this.loading = bool;
},
setOverflow (bool) {
this.overflow = bool;
},
requestData() {
console.log("aaa");
this.$emit("requestData");
},
getScrollHeight() {
return this.$refs.scrollC.scrollHeight;
},
scrollYTo(num) {
this.$refs.scrollC.scrollTop = num;
},
scrollFn(e) {
if (this.loading || this.overflow) {
return;
}
const scrollTop = e.currentTarget.scrollTop;
this.scrollFnDebounce(60, scrollTop);
}
}
};
</script>
<style lang="scss" scoped>
.scroll-c {
height: 100%;
overflow-y: auto;
position: relative;
.loading-top-c {
height: 64px;
}
.scroll-item {
// height: 200px;
// margin-bottom: 10px;
position: relative;
}
::v-deep .van-loading {
text-align: center;
margin: 20px;
}
}
</style>