您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“基于vue2如何實現(xiàn)上拉加載功能”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“基于vue2如何實現(xiàn)上拉加載功能”這篇文章吧。
具體內(nèi)容如下
因為我們項目中,還用了swiper。很多都是滑動切換的,但是又得上拉加載,所以導(dǎo)致,很多UI框架,我們用了,都有不同的bug出現(xiàn),沒辦法,最后寫了一個。代碼如下(這個因為很多地方會用,所以建議放在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 { // 最下面出現(xiàn)的div的位移 translate: 0, // 選擇滾動事件的監(jiān)聽對象 scrollEventTarget: null, containerFilled: false, bottomText: '', // class類名 bottomDropped: false, // 獲取監(jiān)聽滾動元素的scrollTop bottomReached: false, // 滑動的方向 down---向下互動;up---向上滑動 direction: '', startY: 0, startScrollTop: 0, // 實時的clientY位置 currentY: 0, topStatus: '', // 上拉加載的狀態(tài) '' pull: 上拉中 bottomStatus: '', }; }, watch: { // 改變當(dāng)前加載在狀態(tài) 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'; // 選擇滾動事件的監(jiān)聽對象 this.scrollEventTarget = this.getScrollEventTarget(this.$el); if (typeof this.bottomMethod === 'function') { // autoFill 屬性的實現(xiàn) 注釋 this.fillContainer(); // 綁定滑動事件 this.bindTouchEvents(); } }, // autoFill 屬性的實現(xiàn) 注釋 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(); } }); } }, // 獲取監(jiān)聽滾動元素的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坐標(biāo) 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) { // 沒有在需要滾動的范圍內(nèi)滾動,不再監(jiān)聽scroll return; } // 實時的clientY位置 this.currentY = event.touches[0].clientY; // distance 移動位置和開始位置的差值 distanceIndex--- let distance = (this.currentY - this.startY) / this.distanceIndex; // 根據(jù) distance 判斷滑動的方向 并賦予變量 direction down---向下互動;up---向上滑動 this.direction = distance > 0 ? 'down' : 'up'; if (this.direction === 'up') { // 獲取監(jiān)聽滾動元素的scrollTop this.bottomReached = this.bottomReached || this.checkBottomReached(); } if (typeof this.bottomMethod === 'function' && this.direction === 'up' && this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) { // 有加載函數(shù),是向上拉,有滾動距離,不是正在加載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>
然后哪個頁面需要,在哪個頁面導(dǎo)入即可: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設(shè)置如下:
export default { name: 'FinancialGroup', props:{ }, data () { return { // 上拉加載數(shù)據(jù) 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; // 每次更迭加載的頁數(shù) if (this.pageNo == this.totalGetCount) { // 當(dāng)allLoaded = true時上拉加載停止 this.loading = false; this.allLoaded = true; } api.commonApi(后臺接口,請求參數(shù)) 這個api是封裝的axios有不懂的可以看vue2+vuex+axios那篇文章 .then(res => { setTimeout(() => { 要使用的后臺返回的數(shù)據(jù)寫在setTimeout里面 this.$nextTick(() => { this.loading = false; }) }, 1000) }); }, handleBottomChange(status) { this.bottomStatus = status; }, }
這樣就完成了。
以上是“基于vue2如何實現(xiàn)上拉加載功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。