目录
PC 端 :
InfiniteScroll 无限滚动
详细说明
v-infinite-scroll 指令
infinite-scroll-disabled 属性
infinite-scroll-distance 属性
总结
使用弊端 :
尝试解决 :
代码实现 :
移动端 :
List 列表
需求背景 :
项目管理列表页面,由于数据量过多时 在 IE 浏览器上面会加载异常缓慢,刚进入时页面空白无数据,导致用户体验感较差,所以需要整改优化。
这里就需要 前后端 联调 调整 了,
后端:需将接口由原来的传给前端的全部数据方式调整为 “分页传输” 方式,也就是前端再多传给后端两个字段值:currentPage:1,// 当前页数;pageSize:10,// 一页显示的条数( 当然这里我们是由后端写死了:5,一页固定传给前端 5 条数据,所以前端此字段可以不传 )
前端:进行 懒加载 处理,也就是 需借助 Element|InfiniteScroll 无限滚动 组件 来实现一个下拉至列表底部时,向后端请求下一页的数据用于拼接至列表数组后再次展示新的内容。【 PC 端 】
接下来就让我们来 了解 & 如何使用 吧:( 可参考 组件的 禁用加载 示例 )
前端:懒加载,移动端 需借助 Vant 2 |List 列表 组件 |基础用法 来实现一个下拉至列表底部时,向后端请求下一页的数据用于拼接至列表数组。
PC 端 :
InfiniteScroll 无限滚动
滚动至底部时,加载更多数据。
在前端开发中,很多页面都需要实现无限滚动的效果,即当页面滚动到底部时,自动加载更多的数据。Element Infinitescroll 是一款方便易用的 Vue 组件,可以帮助我们快速实现无限滚动功能。
基本用法
Element Infinitescroll 提供了一个 v-infinite-scroll 指令,可以直接在需要无限滚动的元素上使用。
项目示例 :
src / views / statistics / index.vue
<template>
<div>
<DefaultReport
v-if="dataList.length > 0"
:dataList.sync="dataList"
:loading.sync="loading"
:noMore="noMore"
@getDataList="getDataList"
/>
</div>
</template>
<script>
import DefaultReport from './component/DefaultReport';
import { getStatisticsData } from '@api/listApi.js';
export default {
components: { DefaultReport },
data() {
return {
loading: false, // 列表加载中...
noMore: false, // 没有更多了
dataList: [], // 页面数据
setFormData: {
surveyId: '',
currentPage: 1, // 当前页数
},
};
},
computed: {
rqObj() {
return this.$route.query || {};
},
},
created() {
if (this.rqObj.id && this.rqObj.id !== null) {
this.setFormData.surveyId = this.rqObj.id;
this.getDataList(this.setFormData);
}
},
methods: {
async getDataList(data) {
let res = await getStatisticsData(data);
const { code, result } = res;
if (code === '0') {
if (result.lists && result.lists.length > 0) {
this.dataList = this.dataList.concat(result.lists);
}
this.loading = false;
// 加载完成后需要将loading设置为false,以便下次触发加载
} else {
// 没有更多数据了(需停止继续加载)
this.loading = false;
this.noMore = false;
}
},
},
};
</script>
<style lang="scss" scoped></style>
src / views / statistics / component / DefaultReport.vue
<template>
<div class="infinite-list-wrapper" style="overflow: auto">
<ul
class="list"
v-if="dataList.length > 0"
v-infinite-scroll="loadMore"
infinite-scroll-disabled="loadDisabled"
>
<!-- :infinite-scroll-disabled="loadDisabled" -->
<li v-for="i in dataList" class="list-item" :key="i">
<!-- 展示数据的内容 -->
{{ i }}
</li>
</ul>
<p v-if="loading">加载中...</p>
<p v-if="noMore">没有更多了</p>
<p v-if="dataList.length === 0">抱歉,暂无数据</p>
</div>
</template>
<script>
export default {
props: {
dataList: {
type: Array,
default: () => [],
},
loading: {
// 标记数据是否正在加载中
type: Boolean,
default: false,
},
noMore: {
// 是否继续加载
type: Boolean,
default: false,
},
},
data() {
return {
// count: 10,
// loading: false,
setFormData: {
surveyId: '',
currentPage: 1, // 当前页数
},
};
},
computed: {
// noMore() {
// return this.count >= 20;
// },
loadDisabled() {
// 是否禁用(false停止加载)
return this.loading || this.noMore;
},
rqObj() {
return this.$route.query || {};
},
},
created() {
if (this.rqObj.id && this.rqObj.id !== null) {
this.setFormData.surveyId = this.rqObj.id;
}
},
methods: {
// 滚动加载方法(在这里进行数据加载操作)
loadMore() {
if (this.noMore) return;
this.$emit('update:loading', true);
this.setFormData.currentPage++;
if (this.$parent.getDataList) {
this.$parent.getDataList(this.setFormData);
} else {
this.$emit('getDataList', this.setFormData);
}
// this.loading = true;
// setTimeout(() => {
// this.count += 2;
// this.loading = false;
// }, 2000);
},
},
};
</script>
<style lang="scss" scoped>
.infinite-list-wrapper {
.list {
min-height: 800px;
overflow-y: auto;
}
}
</style>
详细说明
v-infinite-scroll 指令
在要实现 滚动加载的列表上 添加 v-infinite-scroll
,并赋值相应的加载方法,可实现滚动到底部时自动执行加载方法。
v-infinite-scroll 指令用于绑定一个滚动到底部时要触发的方法。
- 示例:v-infinite-scroll="loadMore"
- loadMore 是一个方法,当页面滚动到底部时会自动调用该方法。
infinite-scroll-disabled 属性
infinite-scroll-disabled 属性用于动态控制是否禁用无限滚动。
- 示例:infinite-scroll-disabled="loadDisabled"
- loadDisabled 是一个数据变量,用于标记数据是否正在加载中。当变量值为 true 时,禁用无限滚动。
infinite-scroll-distance 属性
infinite-scroll-distance 属性用于控制触发加载的距离。
- 示例:infinite-scroll-distance="0"
- 0 表示距离底部还有 0 个像素时触发加载。
总结
通过 Element Infinitescroll ,我们可以方便地实现页面的无限滚动效果。
只需要使用 v-infinite-scroll 指令绑定方法,控制 infinite-scroll-disabled 属性
和 infinite-scroll-distance 属性,我们就可以加载更多的数据,提升用户体验。
使用弊端 :
后来 项目经理 测试 觉得页面本身有一个滚动条了,里面的数据列表(也就是使用了 Element Infinitescroll 无限滚动组件,绑定了 v-infinite-scroll 指令方法的 列表 盒子 )也会有一个滚动条,所以感觉界面 使用 体验感 较差,想着只用页面本身的滚动条就好,如此一来,里面的盒子就不能设置属性 style="overflow:auto" 了。
尝试解决 :
既然不能通过里面盒子的滚动条滚动至底部去加载了,那就把它提出来,就是把 v-infinite-scroll 指令方法 绑定在这个页面最大的元素上面,尝试了之后,发现一进入页面就会不断触发 v-infinite-scroll="loadMore" 的方法,导致会在调用好多次请求之后把页面所有的数据都一次性渲染展示了出来。没办法,既然尝试无果,就只好另辟蹊径。百度了一番:如何判断浏览器滚动条滚到底部,因此来侧面实现此组件的功能( 也就是说不用 Element 提供的 Infinitescroll 无限滚动组件了 )
代码实现 :
src / views / statistics / index.vue
<template>
<div>
<DefaultReport
v-if="dataList.length > 0"
:dataList.sync="dataList"
:loading.sync="loading"
:noMore="noMore"
@getDataList="getDataList"
/>
</div>
</template>
<script>
import { debounce } from '@/utils/tools'; // 防抖方法节约性能
import { getStatisticsData } from '@api/listApi.js';
import DefaultReport from './component/DefaultReport';
export default {
components: { DefaultReport },
/* 主要就是修改其父组件内容,子组件删除掉无用代码就好 */
mounted() {
// 监听浏览器滚动条是否滚动至底部
this.$nextTick(() => {
window.addEventListener('scroll', this.handleScrollMoreMore, true); // 监听页面滚动
});
},
methods: {
handleScrollMoreMore: debounce(function () {
// 无数据时停止向下
if (this.noMoreLoad) return;
let docEl = document.documentElement;
let dobo = document.body;
// 变量scrollTop是滚动条滚动时,距离顶部的距离
let scrollTop = docEl.scrollTop || dobo.scrollTop;
// 变量windowHeight是可视区的高度
let windowHeight = docEl.clientHeight || dobo.clientHeight;
// 变量scrollHeight是滚动条的总高度
let scrollHeight = docEl.scrollHeight || dobo.scrollHeight;
// 滚动条到底部的条件
if (scrollTop + windowHeight === scrollHeight) {
this.loading = true;
this.setFormData.currentPage++;
this.getDataList(this.setFormData);
}
}, 400),
// ======================================================
async getDataList(data) {
let res = await getStatisticsData(data);
const { code, result } = res;
if (code === '0') {
if (result.lists && result.lists.length > 0) {
this.dataList = this.dataList.concat(result.lists);
}
this.loading = false;
// 加载完成后需要将loading设置为false,以便下次触发加载
} else {
// 没有更多数据了(需停止继续加载)
this.loading = false;
this.noMore = false;
}
},
},
};
// Tips 小提示 :假如 页面获取的高度值以及滚动的高度值一直不变的话,自行检查一下页面样式问题
</script>
移动端 :
List 列表
Vant 2 / List 列表 / 介绍
瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,会触发事件并加载更多列表项。
<template>
<div>
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell v-for="item in list" :key="item" :title="item" />
</van-list>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
loading: false,
finished: false,
};
},
methods: {
onLoad() {
// 异步更新数据
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
setTimeout(() => {
for (let i = 0; i < 10; i++) {
this.list.push(this.list.length + 1);
}
// 加载状态结束
this.loading = false;
// 数据全部加载完成
if (this.list.length >= 40) {
this.finished = true;
}
}, 1000);
},
},
};
</script>
项目实战 :文章来源:https://www.toymoban.com/news/detail-778090.html
src / views / index.vue文章来源地址https://www.toymoban.com/news/detail-778090.html
<template>
<div>
<van-list
v-if="dataList.length > 0"
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<p>{{ 'ItemName' }}</p>
<van-cell v-for="item in dataList" :key="item" :title="item" />
</van-list>
<div v-else>
<img src="" alt="空" />
<p>暂无数据</p>
</div>
</div>
</template>
<script>
import { getStatisticsData } from '@api/index';
export default {
data() {
return {
dataList: [], // 列表数据
loading: false, // 加载显示与否
finished: false, // 是否加载完毕
formData: {
surverId: '',
currentPage: 1, // 当前页数
},
};
},
computed: {
rqObj() {
return this.$route.query || {};
},
},
created() {
if (this.rqObj.id && this.rqObj.id !== null) {
this.formData.surveyId = this.rqObj.id;
this.getDataList(this.formData);
}
},
methods: {
onLoad() {
// 滚动到底部时触发
this.formData.currentPage++;
this.getDataList(this.formData);
},
async getDataList(data) {
let res = await getStatisticsData(data);
const { code, result } = res;
if (code === '0') {
if (result.lists && result.lists.length > 0) {
this.dataList = this.dataList.concat(result.lists);
}
// 加载状态结束
this.loading = false;
// 加载完成后需要将loading设置为false,以便下次触发加载
} else {
// 没有更多数据了(需停止继续加载)
this.loading = false;
this.finished = true; // 数据全部加载完成(true)
}
},
},
};
</script>
到了这里,关于Element|InfiniteScroll 无限滚动组件的具体使用方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!