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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章