每个 Vue 实例都实现了事件接口:
- 使用 $on(eventName) 监听事件
- 使用 $emit(eventName) 触发事件
一旦 $emit 事件触发 $on 则监听到 $emit 所派发的事件,派发出的命令和执行派执命令所要做的事都是一一对应的。
//滑动触底加载组件 scrollLower.vue
<template>
<div>
<slot name="list"></slot>
<div v-show="!isLoading && isDone">
<slot>没有更多数据了</slot>
</div>
<div v-show="isLoading">
<slot>加载中</slot>
</div>
</div>
</template>
<script>
export default {
props: {
//父组件传递方法
onScroll: {
type: Function,
required: true
},
},
data() {
return {
isLoading: false, //false表示加载更多,true表示加载完毕
isDone: false //false代表数据没有完全加载完毕
};
},
methods: {
init() {
this.$on("loadedDone", () => {
this.isLoading = false;
this.isDone = true;
});
//恢复可加载状态
this.$on("finishLoading", () => {
console.log("fhdjfdj");
this.isLoading = true;
});
},
//获取ScrollTop
getScrollTop() {
var scrollTop = 0,bodyScrollTop = 0,documentScrollTop = 0;
if (document.body) {
bodyScrollTop = document.body.scrollTop;
}
if (document.documentElement) {
documentScrollTop = document.documentElement.scrollTop;
}
scrollTop =bodyScrollTop - documentScrollTop > 0 ? bodyScrollTop : documentScrollTop;
return scrollTop;
},
//下拉触底监听事件处理方法
scrollHander() {
if (this.isLoading || this.isDone) return;
//文本可见高度
let baseHeight = document.documentElement.clientHeight;
//可滑动包括溢出隐藏部分
let moreHeight = document.body.scrollHeight;
//滑动距离
let scrollTop = this.getScrollTop();
//判断是否触底
if (baseHeight + scrollTop > moreHeight) {
this.isLoading = true;
this.onScroll();
}
}
},
mounted() {
this.scrollview = window;
this.scrollview.addEventListener("scroll", this.scrollHander, false);
this.$nextTick(this.init());
}
};
</script>
父组件使用scrollLower
<template>
<div>
<scrollLower:onScroll="loadingData" ref="scroll">
<ul slot="list" class="ul">
<li v-for="item in list" class="listitem">{{item}}</li>
</ul>
</scrollLower>
</div>
</template>
<script>
import scrollLower from "@/components/scrollLower";
export default {
components: { scrollLower },
data() {
return {
list: [1, 2, 3, 4, 5, 6, 7, 5, 8, 9, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0]
};
},
methods:{
//当滚动到底部时执行加载数据的函数
loadingData(){
setTimeout(()=>{
this.list.push('d')
this.$refs.scroll.$emit('loadedDone')
},2000)
}
}
};
</script>
<style>
.listitem{
width: 500px;
height: 150px;
border: 1px solid;
}
</style>