-
安装引入lodash
npm i --save lodash
import _throttle from 'lodash/throttle'
-
给Vue组件根标签添加滚动事件,PC端是滚动实现懒加载,所以必须要有滚动事件,不过这个滚动事件不一定是在组件的根标签上,也可以是在其他元素,但是这个元素必须是列表元素的父级以上的组件。
<div id="recomand-show" @scroll="onScroll"></div>
-
下面来看看懒加载的实现的JS方法
//懒加载的方法 onScroll: _throttle(function () { var info = document.getElementById('recomand-show'); var scrollTop = info.scrollTop; var clientHeight = info.clientHeight; var scrollHeight = info.scrollHeight; if (scrollHeight - clientHeight < scrollTop + 0.1) { if(this.loading) { this.loading = false; this.addList(); } } }), async addList () { this.pages.pageNum ++; await recommendList(this.pages).then(res => { this.recommandCourse = [...this.recommandCourse,...res.rows]; this.recommandTotal = res.total; }) if (this.recommandCourse.length >= this.recommandTotal) { this.loading = false return } this.loading = true },
上面的代码中用到了如下几种JS属性:
-
scrollTop
:scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0。
-
clientHeight
:clientHeight 属性是一个只读属性,它返回该元素的像素高度,高度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条,是一个整数,单位是像素 px。 -
scrollHeight
:clientHeight 属性是一个只读属性,它返回该元素的像素高度,高度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条,是一个整数,单位是像素 px。
用一张图来说明他们的关系
scrollHeight - clientHeight < scrollTop + 0.1
当这句代码返回true
时我们可以确定在可视区域下面是没有卷进去的内容的,也就是上图深蓝色区域的下面是没有内容的,那么此时我们就要去调用接口获取新的数据。 -
-
_throttle
方法主要是为了防止页面抖动 -
完整代码如下:
<template> <div class="recommand-course" id="recomand-show" @scroll="onScroll" v-loading="recommandCourseLoading"> <div class="rec-course"> <div class="course-list-show"> <div class="content_header"> <div class="title">推荐课程</div> </div> <div v-if="isRecommandShow"> <ul class="course"> <li class="course_item" :class="(index+1) % 3 === 0 ? 'mar_right' : ''" v-for="(item,index) in recommandCourse" :key="index"> <div class="img" @click="toVideo(item.url)"> <img :src="item.cover" alt=""/> </div> <h3>{ {item.name}}</h3> <p>{ {item.introduction}}</p> </li> </ul> <div class="tip" v-if="loading">加载中...</div> <div class="tip" v-else>没有更多了</div> </div> <div class="none-course" v-else> <el-empty description="暂无数据"></el-empty> </div> </div> </div> </div> </template> <script> import { recommendList } from '@/api/course/courseController.js' import _throttle from 'lodash/throttle' export default { data () { return { recommandCourse:[], recommandTotal:0, loading: true, pages:{ pageSize: 9, pageNum: 1, }, recommandCourseLoading: false, isRecommandShow: true, } }, created () { this.getRecommendList(); }, methods: { //拼接前缀 addPre(item) { return `${process.env.VUE_APP_MINIO_API}/train-platform/${item}` }, getRecommendList () { this.recommandCourseLoading = true; recommendList(this.pages).then(res => { this.recommandCourse = [...this.recommandCourse,...res.rows]; this.recommandTotal = res.total; if(this.recommandCourse !== null && this.recommandCourse.length > 0) { this.isRecommandShow = true; } else { this.isRecommandShow = false } this.recommandCourseLoading = false }) }, //懒加载的方法 onScroll: _throttle(function () { console.log('scroll'); var info = document.getElementById('recomand-show'); var scrollTop = info.scrollTop; var clientHeight = info.clientHeight; var scrollHeight = info.scrollHeight; if (scrollHeight - clientHeight < scrollTop + 0.1) { console.log('loading',this.loading); if(this.loading) { this.loading = false; this.addList(); console.log(123) } } }), async addList () { console.log('addList'); // console.log('setTimeout',this.pages.pageNum++); this.pages.pageNum ++ await recommendList(this.pages).then(res => { this.recommandCourse = [...this.recommandCourse,...res.rows]; this.recommandTotal = res.total }) console.log('此时数组的长度',this.recommandCourse.length); if (this.recommandCourse.length >= this.recommandTotal) { this.loading = false return } this.loading = true }, toVideo(url) { this.$router.push({ name: 'PlayVideo', query: { url } }) } } } </script> <style lang="scss" scoped> .recommand-course { width: 100%; height: 80vh; overflow-y: scroll; display: flex; justify-content: center; .rec-course { // width: 70%; .course-list-show { width: 940px; // margin-left: 27%; } } } .recommand-course::-webkit-scrollbar {display:none} .content_header { // display: flex; // align-items: center; position: relative; width: 100%; height: 50px; div { position: absolute; top: 50%; transform: translateY(-50%); } } .title { // width: 84%; font-size: 18px; font-weight: 400; font-family: "思源黑体"; // margin-top: 10px; padding: 0px; text-align: left; // line-height: 24px; } .course { width: 100%; // height: 700px; display: flex; flex-wrap: wrap; // justify-content: space-between; margin-top: 30px; padding: 0px; .course_item { width: 300px; height: 100%; margin-right: 20px; margin-bottom: 25px; list-style: none; .img { position: relative; width: 300px; height: 200px; cursor: pointer; img{ width: 100%; height: 100%; object-fit:cover; } .approval{ width: 300px; height: 200px; position: absolute; top: 0px; left: 0px; background-color: rgba($color: #000000, $alpha: 0.5); display: flex; justify-content: center; align-items: center; p { font-size: 16px; color: #fff; } } } h3{ font-family: '思源黑体'; color: rgba(31, 31, 31, 1); font-size: 16px; font-weight: 500; line-height: 30px; margin:4px 0px 3px 0px; } p { margin: 0px; color: rgba(97, 97, 97, 1); font-size: 12px; font-weight: 400; font-family: '思源黑体'; } } .mar_right { margin-right: 0px; } } .tip { color: gainsboro; text-align: center; padding-bottom: 20px; } </style>
PC端实现列表懒加载
猜你喜欢
转载自blog.csdn.net/weixin_45566730/article/details/126528200
今日推荐
周排行