列表在固定区域内滚动,上拉触底加载下一页

14 阅读1分钟

背景 常见的UI组件库的list组件已经支持了触底加载 当list组件不能满足定制化的需求时,需要自己通过for循环渲染列表,并实现触底加载

实现 以下是一个触底加载数据的实例 实例使用Vue.js实现

拓展 当然你也可以监听触底事件,执行其他的操作,只需要把getList方法调用替换掉即可

循环渲染列表数据

<div class="content" ref="scrollview">
 <!-- 列表内容 -->
  <ul class="t-body" v-for="item in list" :key="item.id">
    <li class="t-row">
      <div class="t-col">{{item.id}}</div>
    </li>
  </ul>
</div>

固定列表滚动区域

.content{
    height: 350px;
    overflow-y: scroll;
}

监听滚动触底事件,加载下一页数据

const page = ref({
  pageNum: 1,
  pageSize: 10,
})
const getList = ()=>{
  const req = {
    ...params,
    ...page.value
  }
  runGetlist(req)
}
getList()
const loading = ref(false)
// 滚动回调函数
const scrollCallback = (e)=>{
  const throttle = (func, delay) => { // 节流方法
    let timer
    return function () {
      if (!timer) {
        timer = setTimeout(() => {
          func.apply(this, arguments);
          timer = null
        }, delay)
      }
    }
  }
  const onBottom = () => { // 触底相应函数
    let clientHeight = e?.clientHeight||0; // 获取可视高度
    let scrollTop = e?.scrollTop||0 // 获取滚动高度
    let scrollHeight = e?.scrollHeight||clientHeight // 滚动条高度
    if (clientHeight + scrollTop >= scrollHeight - 10) {
      if(stageList.value.length<listTotal.value && loading.value===false){
        page.value.pageNum++
        loading.value = true
        getList()
      }
    }
  }
  return throttle(onBottom, 500)
}
// 滚动监听函数
const handleScroll = () => {
  const scrollview = document.getElementById('scrollview')
  if(scrollview){
    scrollview.addEventListener('scroll', scrollCallback(scrollview))
  }
}
// 滚动监听移除函数
const removeScroll = ()=>{
  const scrollview = document.getElementById('scrollview')
  if(scrollview){
    scrollview.removeEventListener('scroll', scrollCallback(scrollview))
  }
}
onMounted(()=>{
  handleScroll()
})
onUnmounted(()=>{
  removeScroll()
})