Vue 觸底加載組件簡單實現


找到一個好用的下拉刷新,上拉加載的vue 插件   vue-scroller, git 地址

return

 

今天寫了個觸底加載的組件,因為經常用到,之前總會遇到一種需求,就是有一個列表,可以實現下拉刷新,上拉加載,

找了一個一個的插件,填了一個一個的坑后,決定自己寫個觸底加載,簡單實現下這個功能,不要跟我說:“這樣不好看,我們要看

有橡皮筋那樣的彈性效果,還要有下拉刷新,巴拉巴拉。。。。”,寫過幾次這種需求的我,已經不在乎這種效果了,丫的全是坑,

一句“可以,但沒必要”,就完了。

廢話說多了,來看下實現觸底加載的幾個步驟

1. 觸底加載的布局,一個高度固定的容器,然后容器里面放一個列表,一般列表的初始高度是大於容器的高度,小於的話它滾動不了,就監聽不到

它有沒有滾到底部了。注意: 容器高度取  clientHeight ,列表高度取  offsetHeight 

2. 監聽容器的滾動事件,在滾動時獲取滾出容器的高度,當滾出的高度加上容器的高度等於列表的高度時就觸底了。觸底加載的組件就這些邏輯了

上觸底加載組件代碼

 1 <template>
 2   <div class="infinite" ref="container" :style="{height: height}">
 3     <div class="inner" ref="inner">
 4       <!-- 列表標題 -->
 5       <slot name="title"></slot>
 6       <!-- 這里放列表 -->
 7       <slot></slot>
 8       <!-- 加載中的動畫 -->
 9       <slot name="loading" v-if="loading"></slot>
10       <!-- 加載完成的動畫 -->
11       <slot name="nomore" v-if="nomore"></slot>
12     </div>
13   </div>
14 </template>
15 <script>
16 export default {
17   name: 'infinite-scroll',
18   props: {
19     height: {
20       type: String,
21       default: '100%'
22     },
23     loading: {
24       type: Boolean,
25       default: false
26     },
27     nomore: {
28       type: Boolean,
29       default: false
30     },
31   },
32   data () {
33     return {
34       containerHeight: 0,
35       innerHeight: 0
36     }
37   },
38   created () {
39 
40   },
41   mounted () {
42     this.containerHeight = this.$refs.container.clientHeight
43     this.innerHeight = this.$refs.inner.offsetHeight
44     this.$refs.container.addEventListener('scroll', this.initScroll)
45   },
46   methods: {
47     initScroll (e) {
48       if (this.loading || this.nomore) return
49       this.innerHeight = this.$refs.inner.offsetHeight
50       let scrollTop = e.target.scrollTop
51       if (scrollTop + this.containerHeight >= this.innerHeight) {
52         console.log('-----------------觸底了-------------');
53         this.$emit('loadBottom')
54       }
55     }
56   }
57 }
58 </script>
59 <style lang="less" scoped>
60   .infinite {
61     width: 100%;
62     background-color: skyblue;
63     overflow: auto;
64     -webkit-overflow-scrolling: touch; // 解決iOS滾動問題
65   }
66 </style>

然后在頁面中使用這個組件,我把組件注冊成全局組件了,所以直接就用在頁面了

 1 <template>
 2   <div class="home">
 3     <div class="scroll">
 4       <infinite-scroll class="infinite" :loading="loading" :nomore="nomore" @loadBottom="loadmore" >
 5         <template slot="title">
 6           <p>這是一個標題</p>
 7         </template>
 8         <p v-for="item in list" :key="item.id">{{ item.name + '---' + item.value }}</p>
 9         <template slot="loading" >
10           <i>加載中</i>
11         </template>
12         <template slot="nomore">
13           <i>沒有更多了</i>
14         </template>
15       </infinite-scroll>
16     </div>
17   </div>
18 </template>
19 <script>
20 export default {
21   data () {
22     return {
23       loading: false,
24       pageSize: 10,
25       pageNumber: 1,
26       total: 0,
27       loadTotal: false,
28       list: []
29     }
30   },
31   created () {
32     this.loadmore()
33   },
34   methods: {
35     async loadmore () {
36       if (this.loading || this.nomore) return
37       this.loading = true
38       const response = await this.$post('******', {
39         pageSize: this.pageSize,
40         pageNumber: this.pageNumber
41       })
42       if ('請求成功') {
43         this.total = response.totalRecord
44         this.list.push(...response.list)
45         if (this.list.length >= this.total) {
46           this.nomore = true
47         } else {
48           this.pageNumber ++
49         }
50       }
51       this.$nextTick(() => {
52         setTimeout(() => {
53           this.loading = false
54         }, 300);
55       })
56     },
57   }
58 }
59 </script>
60 <style lang="less" scoped>
61 .home {
62   padding: 1px;
63   .scroll {
64     width: 80%;
65     height: 7rem;
66     margin: 1rem auto;
67     .infinite {
68       font-size: .32rem;
69       line-height: .8rem;
70       overflow: auto;
71       i {
72         font-size: .24rem;
73         text-align: center;
74         width: 100%;
75         display: block;
76       }
77     }
78   }
79 }
80 </style>

組件中有這么幾個參數時必傳的

1.  loading  節流的,開始加載時是  true  加載更多的請求完成並顯示在頁面上了改為   false 

2.   nomore 所有數據是否都已加載完成

3.  loadBottom 監聽這個事件,事件觸發后就是要加載更多了

4. 還有一些 slot ,用則寫,不用就不管了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM