最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

基于vue2实现上拉加载功能

来源:懂视网 责编:小OO 时间:2020-11-27 22:24:54
文档

基于vue2实现上拉加载功能

本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下:因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面)。
推荐度:
导读本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下:因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面)。

本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下

因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面):

<template>
 <div class="loadmore">
 <slot></slot>
 <slot name="bottom">
 </slot>
 </div>
</template>

<style>
 .loadmore{
 width:100%;
 }
</style>

<script>
 export default {
 name: 'loadmore',
 props: {
 maxDistance: {
 type: Number,
 default: 0
 },
 autoFill: {
 type: Boolean,
 default: true
 },
 distanceIndex: {
 type: Number,
 default: 2
 },
 bottomPullText: {
 type: String,
 default: '上拉刷新'
 },
 bottomDropText: {
 type: String,
 default: '释放更新'
 },
 bottomLoadingText: {
 type: String,
 default: '加载中...'
 },
 bottomDistance: {
 type: Number,
 default: 70
 },
 bottomMethod: {
 type: Function
 },
 bottomAllLoaded: {
 type: Boolean,
 default: false
 },
 },
 data() {
 return {
 // 最下面出现的div的位移
 translate: 0,
 // 选择滚动事件的监听对象
 scrollEventTarget: null,
 containerFilled: false,
 bottomText: '',
 // class类名
 bottomDropped: false,
 // 获取监听滚动元素的scrollTop
 bottomReached: false,
 // 滑动的方向 down---向下互动;up---向上滑动
 direction: '',
 startY: 0,
 startScrollTop: 0,
 // 实时的clientY位置
 currentY: 0,
 topStatus: '',
 // 上拉加载的状态 '' pull: 上拉中
 bottomStatus: '',
 };
 },
 watch: {
 // 改变当前加载在状态
 bottomStatus(val) {
 this.$emit('bottom-status-change', val);
 switch (val) {
 case 'pull':
 this.bottomText = this.bottomPullText;
 break;
 case 'drop':
 this.bottomText = this.bottomDropText;
 break;
 case 'loading':
 this.bottomText = this.bottomLoadingText;
 break;
 }
 }
 },
 methods: {
 onBottomLoaded() {
 this.bottomStatus = 'pull';
 this.bottomDropped = false;
 this.$nextTick(() => {
 if (this.scrollEventTarget === window) {
 document.body.scrollTop += 50;
 } else {
 this.scrollEventTarget.scrollTop += 50;
 }
 this.translate = 0;
 });
 // 注释
 if (!this.bottomAllLoaded && !this.containerFilled) {
 this.fillContainer();
 }
 },

 getScrollEventTarget(element) {
 let currentNode = element;
 while (currentNode && currentNode.tagName !== 'HTML' &&
 currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
 let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
 if (overflowY === 'scroll' || overflowY === 'auto') {
 return currentNode;
 }
 currentNode = currentNode.parentNode;
 }
 return window;
 },
 // 获取scrollTop
 getScrollTop(element) {
 if (element === window) {
 return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
 } else {
 return element.scrollTop;
 }
 },
 bindTouchEvents() {
 this.$el.addEventListener('touchstart', this.handleTouchStart);
 this.$el.addEventListener('touchmove', this.handleTouchMove);
 this.$el.addEventListener('touchend', this.handleTouchEnd);
 },
 init() {
 this.bottomStatus = 'pull';
 // 选择滚动事件的监听对象
 this.scrollEventTarget = this.getScrollEventTarget(this.$el);
 if (typeof this.bottomMethod === 'function') {
 // autoFill 属性的实现 注释
 this.fillContainer();
 // 绑定滑动事件
 this.bindTouchEvents();
 }
 },
 // autoFill 属性的实现 注释
 fillContainer() {
 if (this.autoFill) {
 this.$nextTick(() => {
 if (this.scrollEventTarget === window) {
 this.containerFilled = this.$el.getBoundingClientRect().bottom >=
 document.documentElement.getBoundingClientRect().bottom;
 } else {
 this.containerFilled = this.$el.getBoundingClientRect().bottom >=
 this.scrollEventTarget.getBoundingClientRect().bottom;
 }
 if (!this.containerFilled) {
 this.bottomStatus = 'loading';
 this.bottomMethod();
 }
 });
 }
 },
 // 获取监听滚动元素的scrollTop
 checkBottomReached() {
 if (this.scrollEventTarget === window) {
 return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
 } else {
 // getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。 right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。
 return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
 }
 },
 // ontouchstart 事件
 handleTouchStart(event) {
 // 获取起点的y坐标
 this.startY = event.touches[0].clientY;
 this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
 this.bottomReached = false;
 if (this.bottomStatus !== 'loading') {
 this.bottomStatus = 'pull';
 this.bottomDropped = false;
 }
 },
 // ontouchmove事件
 handleTouchMove(event) {
 if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
 // 没有在需要滚动的范围内滚动,不再监听scroll
 return;
 }
 // 实时的clientY位置
 this.currentY = event.touches[0].clientY;
 // distance 移动位置和开始位置的差值 distanceIndex---
 let distance = (this.currentY - this.startY) / this.distanceIndex;
 // 根据 distance 判断滑动的方向 并赋予变量 direction down---向下互动;up---向上滑动
 this.direction = distance > 0 ? 'down' : 'up';
 if (this.direction === 'up') {
 // 获取监听滚动元素的scrollTop
 this.bottomReached = this.bottomReached || this.checkBottomReached();
 }
 if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
 this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
 // 有加载函数,是向上拉,有滚动距离,不是正在加载ajax,没有加载到最后一页
 event.preventDefault();
 event.stopPropagation();
 if (this.maxDistance > 0) {
 this.translate = Math.abs(distance) <= this.maxDistance
 ? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
 } else {
 this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
 }
 if (this.translate > 0) {
 this.translate = 0;
 }
 this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
 }
 },
 // ontouchend事件
 handleTouchEnd() {
 if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
 this.bottomDropped = true;
 this.bottomReached = false;
 if (this.bottomStatus === 'drop') {
 this.translate = '-50';
 this.bottomStatus = 'loading';
 this.bottomMethod();
 } else {
 this.translate = '0';
 this.bottomStatus = 'pull';
 }
 }
 this.direction = '';
 }
 },
 mounted() {
 this.init();
 }
 };
</script>

然后哪个页面需要,在哪个页面导入即可:import LoadMore from './../common/loadmore.vue';在需要引入他的页面写法如下:

<template>
 <section class="finan">
 <!-- 上拉加载更多 -->
 <load-more
 :bottom-method="loadBottom"
 :bottom-all-loaded="allLoaded"
 :bottomPullText='bottomText'
 :auto-fill="false"
 @bottom-status-change="handleBottomChange"
 ref="loadmore">
 <div>
 这里写你需要的另外的模块
 </div>
 <div v-show="loading" slot="bottom" class="loading"> 这个div是为让上拉加载的时候显示一张加载的gif图
 <img src="./../../assets/main/uploading.gif">
 </div>
 </load-more>
 </section>
</template>

然后在此页面的data里和methods设置如下:

 export default {
 name: 'FinancialGroup',
 props:{
 
 },
 data () {
 return {
 // 上拉加载数据
 scrollHeight: 0,
 scrollTop: 0,
 containerHeight: 0,
 loading: false,
 allLoaded: false,
 bottomText: '上拉加载更多...',
 bottomStatus: '',
 pageNo: 1,
 totalCount: '',
 }
 },
 methods: {
 /* 下拉加载 */
 _scroll: function(ev) {
 ev = ev || event;
 this.scrollHeight = this.$refs.innerScroll.scrollHeight;
 this.scrollTop = this.$refs.innerScroll.scrollTop;
 this.containerHeight = this.$refs.innerScroll.offsetHeight;
 },
 loadBottom: function() {
 this.loading = true;
 this.pageNo += 1; // 每次更迭加载的页数
 if (this.pageNo == this.totalGetCount) {
 // 当allLoaded = true时上拉加载停止
 this.loading = false;
 this.allLoaded = true;
 }
 api.commonApi(后台接口,请求参数) 这个api是封装的axios有不懂的可以看vue2+vuex+axios那篇文章
 .then(res => {
 setTimeout(() => {
 要使用的后台返回的数据写在setTimeout里面
 this.$nextTick(() => {
 this.loading = false;
 })
 }, 1000)
 });
 },
 handleBottomChange(status) {
 this.bottomStatus = status;
 },
 }

这样就完成了。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

基于vue2实现上拉加载功能

本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下:因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面)。
推荐度:
标签: VUE 实现 上拉
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top