vue項目中純手擼代碼實現滾動加載

在當前列表有很多數據的時候,我們一般會採用分頁加載數據,這裏我們也可以通過滾動加載更多數據
在這裏我們先要知道滾動到什麼時候,開始請求數據。
外層盒子設置overflow:auto
內層盒子高度不定。
超出外層盒子滾動。
當內部盒子滾動到距離外部盒子底部50px的時候開始加載數據。

頁面佈局

<div class="history-list-box scroll-bar" ref="scrollBox">
  <ul class="history-list" id="history-list" v-if="historySubList.length > 0">
    <li v-for="(h, k) in historySubList" :key="k">
      <div class="history-item">
        <div v-if="h.state === '1'" class="sub-flag-box">
          <img src="../../assets/img/myReport/dy.png" alt="sub-icon">
          <p>已訂閱</p>
        </div>
        <div v-else-if="h.state === '0'" class="sub-flag-box">
          <img src="../../assets/img/myReport/cancel.png" alt="sub-cancel-icon">
          <p>取消訂閱</p>
        </div>
        <div class="sub-desc" :class="{'sub-cancel': h.state === '0'}">
          <p class="sub-tit">{{h.topicName}}</p>
          <p class="sub-topic">{{h.themeName}}</p>
          <p class="sub-date">{{h.createTime}}</p>
        </div>
      </div>
      <div class="baseline"></div>
    </li>
  </ul>
  <p v-else  style="margin-top: .5rem; font-size: .16rem; color: #ffffff">暫無歷史訂閱記錄</p>
</div>

業務邏輯代碼

export default {
	data(){
		return {
		  // 滾動分頁
	      pageInfo: {
	        page: 1,
	        limit: 10
	      },
	      // 是否進行滾動加載
	      pageFlag: true,
	      // 返回的數據
	      historySubList: [],
	      // 計步器
	      limitWatcher: 1
		}
	},
	mounted() {
	 	// 監聽外部盒子的滾動事件
	 	this.$refs.scrollBox.addEventListener('scroll', this.handleScroll)
	},
	methods: {
		// 獲取接口數據
	    getHistoryListData (type = '') {
	      let jsonData = {
	        data: type,
	        pageInfo: {
	          page: this.pageInfo.page,
	          limit: this.pageInfo.limit
	        }
	      }
	      topicReport.myReport.historySubListData(jsonData).then((res) => {
	        if (res.code === 0) {
	          this.historySubList = res.data
	          // 關鍵代碼 根據是否大於後臺返回的數據總數,來決定是否繼續滾動加載
	          this.pageFlag = this.pageInfo.limit <= res.totalNum
	        }
	      })
	    },
	    // 監聽滾動
	    handleScroll () {
	      let outerClientHeight = this.$refs.scrollBox.clientHeight // 外層盒子可視高度
	      let outerScrollTop = this.$refs.scrollBox.scrollTop // 外層盒子捲去的高度
	      let innerScrollHeight = document.querySelector('#history-list').scrollHeight // 內層盒子全部的高度
	      // 當距離外層盒子底部50px的時候開始記載數據
	      if (((innerScrollHeight - outerScrollTop) - outerClientHeight) <= 50) {
	        if (this.pageFlag) {
	          // 每次滾動符合條件,計步器加1
	          this.limitWatcher++
	          // 每次累加10條
	          this.pageInfo.limit = this.limitWatcher * 10
	          // 關閉滾動控制開關,防止一直滾動一直累加,一直請求數據
	          this.pageFlag = false
	          this.getHistoryListData()
	        }
	      }
	    }
	}
}

外部盒子與內部盒子代碼

.history-list-box {
  flex: 1;
  width: 100%;
  padding: 10/96rem 22/96rem .2rem 10/96rem;
  box-sizing: border-box;
  overflow: auto;
  .history-list {
    display: flex;
    flex-direction: column;
    align-items: center;
    li {
      width: 100%;
      height: 108/96rem;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      .history-item {
        flex: 1;
        width: 100%;
        padding: .2rem 0;
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: -5/96rem;
        .sub-flag-box {
          display: flex;
          flex-direction: column;
          align-items: center;
          width: 100/96rem;
          height: 100%;
          img {
            width: 31/96rem;
            height: 30/96rem;
            margin-bottom: 11/96rem;
          }
          p {
            font-size: 14/96rem;
            color: #2E4A8F;
          }
        }
        .sub-desc {
          flex: 1;
          height: 100%;
          margin-left: .4rem;
          display: flex;
          flex-direction: column;
          align-items: flex-start;
          color: #ffffff;
          padding: 3px 5px;
          .sub-tit {
            font-size: .14rem;
            margin-bottom: .06rem;
            color: #cccccc;
          }
          .sub-topic {
            color: #cccccc;
            font-size: .14rem;
            margin-bottom: .06rem;
          }
          .sub-date {
            color: #cccccc;
            font-size: .14rem;
          }
        }
        .sub-cancel {
          opacity: 0.7;
          background-image: linear-gradient(-90deg, #142A9C 0%, rgba(5,46,100,0.00) 60%);
          border-radius: 3px;
        }
      }
      .baseline {
        width: 100%;
        height: 2px;
        background: url("../../assets/img/myReport/right-baseline.png") no-repeat center center;
        background-size: 100% 100%;
      }
    }
  }
  .no-history {
    width: 100%;
    margin-top: .5rem;
    font-size: .15rem;
  }
}

/*滾動條樣式*/
/*定義滾動條寬高及背景,寬高分別對應橫豎滾動條的尺寸*/
.scroll-bar::-webkit-scrollbar{
    width: 4px;
    height: 6px;
    border-radius: 10px;
    background-color: transparent;
}
/*定義滾動條的軌道,內陰影及圓角*/
.scroll-bar::-webkit-scrollbar-track{
    -webkit-box-shadow: inset 0 0 6px #01192B;
    background-color: transparent;
    border-radius: 10px;
}
/*定義滑塊,內陰影及圓角*/
.scroll-bar::-webkit-scrollbar-thumb{
    height: 20px;
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 6px #01192B;
    background-color: #0672C4;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章