首先我们项目需要实现用户进来只展示屏幕可见的内容,滚动条滑动到底部才加载第二屏幕的内容,并且不是相同的接口获取的更多,导致vant中的list用不了,
首先要确定是哪个页面需要滚动条,项目需求是上方有个固定的tab栏,并且点击tab切换保存滚动条位置,这需要算好滚动屏幕的高度,而不能使用整个页面的滚动条,这样是记不住滚动条位置的
vant-tab切换代码如下:
<van-tabs class="homeTab" v-model="active" swipeable sticky animated background="#d20309" color="#fff" title-active-color="#fff" title-inactive-color="#f4cccd">
<van-tab title="首页" key="homePage">
<home-page :divHeight="commentHeight"></home-page>
</van-tab>
<van-tab title="专题" key="focusNews">
<focusNews :divHeight="commentHeight" ></focusNews>
</van-tab>
</van-tabs>
使用一下代码算出内容的高度并且传递给子组件homePage
mounted() {
//为了获取除了顶部fixed和底部fixed距离,中间展示的内容高度,这样滚动条可以保存固定高度
this.$nextTick(function () {
this.commentHeight = this.curHeight
- document.getElementsByClassName('headerUl')[0].clientHeight
- document.getElementsByClassName('van-tabs__wrap')[0].clientHeight
- document.getElementsByClassName('van-tabbar__placeholder')[0].clientHeight-2
});
},
//获取整个页面的展示高度
beforeMount() {
let h = document.documentElement.clientHeight || document.body.clientHeight;
this.curHeight = h; //减去页面上固定高度height
},
// 下面是homePage 中的代码
<div v-bind:style="{height:divHeight+'px',overflowY:'auto'}" class="homePage" @scroll="scrollEvent"></div>
//注意:要把整个homePage显示的区域使用一个class名标记,为了区分是哪个tab中的加载中,使用@scroll方法调取滚动条事件
//下面是scrollEvent方法
methods: {
scrollEvent(e) {
if (this.skeletonLoading2 == true) {
return
}
//监听滚动条事件以便加载第二屏
let scrollHeight = Math.ceil(e.srcElement.scrollTop + e.srcElement.offsetHeight)
if (scrollHeight >= e.srcElement.scrollHeight) {
let that = this
that.$loadingOrMore('loading','home');//加载中和没有更多的插件(稍后写该插件)
let loading = setTimeout(function () {
that.skeletonLoading2 = true;//为了控制当没有更多的时候就不在调用插件
this.onLoad2()//调用第二屏的ajax
},1000)
}
},
},
下面为插件$loadingOrMore方法在p-loadingOrMore.js中
import Vue from 'vue'
import loadingOrNoMore from '@/components/loading/loadingOrNoMore'
Vue.prototype.$loadingOrMore = (isShow,el) => {
let tag = document.createElement('div');
tag.className = 'l-loadingDiv';
!document.querySelector('.l-loadingDiv')&&document.querySelector('#app').appendChild(tag)
const loadingMore = Vue.extend(loadingOrNoMore);
let instance = new loadingMore({
propsData: { // 使用loadingMore向子组件传参,这里是关键!
isShow: isShow //传入一个回调函数
}
});
// let n = instance.$mount('.l-loadingDiv');
// let html = n.$el.outerHTML
if(el === undefined){
let n = instance.$mount('#loadingNow')
}else {
let n = instance.$mount('.'+ el +' #loadingNow')
}
}
loadingOrNoMore.vue 中的代码
<template>
<div id="loadingNow" class="van-list__loading" v-if="isShow == 'loading'" style="text-align: center;padding: 10px;">
<div class="van-loading van-loading--circular" >
<span class="van-loading__spinner van-loading__spinner--circular" style="width: 16px; height: 16px;">
<svg viewBox="25 25 50 50" class="van-loading__circular">
<circle cx="50" cy="50" r="20" fill="none">
</circle></svg>
</span>
<span class="van-loading__text">加载中</span>
</div>
</div>
<div id="loadingNow" v-else>
<van-divider >没有更多了</van-divider>
</div>
</template>
<script>
export default {
name: "loadingNow",
props:["isShow"],
created() {
console.log(this.isShow)
}
}
</script>
<style scoped>
</style>
为什么写这么多的id相同呢,因为我也没找到好的办法可以解决当找不到#loadingNow就导致报错
l
o
a
d
i
n
g
O
r
M
o
r
e
,
方
法
解
释
当
传
递
参
数
为
l
o
a
d
i
n
g
时
则
为
加
载
中
显
示
,
并
且
第
二
参
数
为
滚
动
条
所
在
的
c
l
a
s
s
t
h
i
s
.
loadingOrMore,方法解释 当传递参数为loading时则为加载中显示,并且第二参数为滚动条所在的class this.
loadingOrMore,方法解释当传递参数为loading时则为加载中显示,并且第二参数为滚动条所在的classthis.loadingOrMore(‘loading’,‘home’);
第一个参数为NoMore则显示没有更多了 ;
this.$loadingOrMore('NoMore,‘home’)
如果有更好的方法,希望大家来完善哟,多多提出