Vue+Vant实现下拉加载功能
作者:猫头_
为了像微信一样方便地加载更多历史消息,这篇文章将为大家介绍我们如何使用vant组件来实现下拉加载功能,感兴趣的小伙伴可以跟随小编一起了解一下
介绍
简介:为了像微信一样方便地加载更多历史消息,我们使用vant组件来实现下拉加载功能。我们对组件进行了改造,将下拉刷新变成了下拉加载更多的形式。这样,用户只需要在第一次下拉时手动开启加载更多,之后只需将页面滑动到顶部,加载更多就会自动触发,直到无数据可加载时,会显示“无更多数据”的提示。
目标:如同微信那般,下拉加载更多历史消息。
组件:利用vant组件的下拉刷新组件。
效果:用户只需在第一次下拉时手动开启加载更多,之后到达顶部时会自动触发加载更多,直到所有数据都加载完毕,此时会出现提示信息:“无更多数据”。
目的:是为了让用户在使用过程中更加方便快捷地加载历史消息,提高用户体验。
该组件官方地址:vant-contrib.gitee.io/vant/v2/#/zh-CN/pull-refresh
效果
我写了一个new promise,延迟了1s返回数据。
开始
引入
import { PullRefresh } from "vant"; export default { components: { "van-pull-refresh": PullRefresh }, }
template上的使用
<div class="refresh"> <van-pull-refresh v-model="isRefreshLoading" pulling-text="下拉加载数据" loosing-text="释放即可刷新" :success-text="isRefreshDisabled ? '无更多数据' : ''" :success-duration="800" :disabled="isRefreshDisabled" @refresh="onRefresh" > <div ref="courseListHeight"> <div v-for="(item, index) in videoList" :key="index" class="content"> {{ item.video_id }} </div> </div> </van-pull-refresh> </div>
使用的参数
我就怕大家懒得打开
Props
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
v-model | 是否处于加载中状态 | boolean | - |
pulling-text | 下拉过程提示文案 | string | 下拉即可刷新... |
loosing-text | 释放过程提示文案 | string | 释放即可刷新... |
success-text | 刷新成功提示文案 | string | - |
success-duration | 刷新成功提示展示时长(ms) | number / string | 500 |
disabled | 是否禁用下拉刷新 | boolean | false |
Events
事件名 | 说明 | 回调参数 |
---|---|---|
refresh | 下拉刷新时触发 | - |
数据处理
处理方案:
1、利用getBoundingClientRect
监听滑块到指定的区域之后,满足判断条件,开始请求下一页数据。
2、阻止在规定的区域内,多次调用api.
3、利用渲染可知高度,使用scrollTo/scrollBy滚动到下拉加载的数据处。
4、请求数据结束,关闭加载中状态以及禁用下拉刷新。
data的数据
params: { page_size: 5, page_num: 1, }, isRefreshLoading: false, // 是否处于加载中状态 isRefreshDisabled: false, // 是否禁用下拉刷新 videoList: [], // 数据内容 courseListPageHeight: 0, // 页面的高度 domVantRefreh: "", // 获取van-loading到顶部的高度 lockOneApiState: false // 防止反复的请求api
再初次进页面需要请求一次接口
beforeMount() { this.getapi(); },
下面就是对后面的数据进行请求,在methods中
onRefresh() { // 获取van-loading到顶部的高度 this.domVantRefreh = document.querySelector(".van-loading"); // 加载监听scroll滚动事件 window.addEventListener("scroll", this.loadingPage); this.params.page_num++; this.getapi(); }, getapi() { getAnchorEnjoySection({ ...this.params }).then(res => { if (res.code == 200) { // 第一次添加数据 if (this.params.page_num == 1) { this.videoList = res.result.video_list; this.$nextTick(() => { // 渲染完成,开始滚动到最低处 window.scrollBy(0, 9999); // 获取第一次的页面列表的高 this.courseListPageHeight = this.$refs.courseListHeight.clientHeight; }); } else { this.videoList.unshift(...(res.result.video_list)); } // 对后面的数据进行处理 if (res.result.video_list.length !== 0 && this.params.page_num !== 1) { this.isRefreshDisabled = false; this.$nextTick(() => { // 获取到需要滚动的高 let heightElement = this.$refs.courseListHeight.clientHeight - this.courseListPageHeight; this.courseListPageHeight = this.$refs.courseListHeight.clientHeight; window.scrollBy(0, heightElement); }); } // 请求无数据的时候 if (res.result.video_list.length == 0) { this.isRefreshDisabled = true; //无数据了,不需要再下拉刷新了 this.isRefreshLoading = false; // 加载状态取消 window.removeEventListener('scroll', this.loadingPage); // 取消监听 } } this.lockOneApiState = true; // 锁状态打开 }); }, loadingPage() { // 由于我们给与了margin-top: 20px;有20的高度,所以使用 0 恰到好处,能再快看到加载状态的时候,进行了加载,同时需要:锁的状态是打开的,并且没有禁用下拉刷新 if (this.domVantRefreh.getBoundingClientRect().top >= 0 && this.lockOneApiState == true && this.isRefreshDisabled == false) { this.params.page_num++; this.getapi(); this.lockOneApiState = false; } }
完整代码
我使用cnd.js
引入总有点小问题,就直接贴出来了,以后解决来再替换。
<template> <div class="refresh"> <van-pull-refresh v-model="isRefreshLoading" pulling-text="下拉加载数据" loosing-text="释放即可刷新" :success-text="isRefreshDisabled ? '无更多数据' : ''" :success-duration="800" :disabled="isRefreshDisabled" @refresh="onRefresh" > <div ref="courseListHeight"> <div v-for="(item, index) in videoList" :key="index" class="content"> {{ item }} </div> </div> </van-pull-refresh> </div> </template> <script> import { PullRefresh } from "vant"; export default { components: { "van-pull-refresh": PullRefresh }, data() { return { dataList: [111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135], params: { page_size: 5, page_num: 1 }, isRefreshLoading: false, // 是否处于加载中状态 isRefreshDisabled: false, // 是否禁用下拉刷新 videoList: [], // 数据内容 courseListPageHeight: 0, // 页面的高度 domVantRefreh: "", // 获取van-loading到顶部的高度 lockOneApiState: false // 防止反复的请求api }; }, beforeMount() { this.getapi(); }, methods: { onRefresh() { // 获取van-loading到顶部的高度 this.domVantRefreh = document.querySelector(".van-loading"); window.addEventListener("scroll", this.loadingPage); this.params.page_num++; this.getapi(); }, getapi() { this.getDataList(this.params).then(res => { console.log(res); if (res.code == 200) { // 第一次添加数据 if (this.params.page_num == 1) { this.videoList = res.result.video_list; this.$nextTick(() => { window.scrollBy(0, 9999); this.courseListPageHeight = this.$refs.courseListHeight.clientHeight; }); } else { this.videoList.unshift(...(res.result.video_list)); } // 对后面的数据进行处理 if (res.result.video_list.length !== 0 && this.params.page_num !== 1) { this.isRefreshDisabled = false; this.$nextTick(() => { let heightElement = this.$refs.courseListHeight.clientHeight - this.courseListPageHeight; this.courseListPageHeight = this.$refs.courseListHeight.clientHeight; window.scrollBy(0, heightElement); }); } // 请求无数据的时候 if (res.result.video_list.length == 0) { this.isRefreshDisabled = true; this.isRefreshLoading = false; window.removeEventListener('scroll', this.loadingPage); } } this.lockOneApiState = true; }); }, loadingPage() { // 由于我们给与了margin-top: 20px;有20的高度,所以使用 0 恰到好处,能再快看到加载状态的时候,进行了加载 if (this.domVantRefreh.getBoundingClientRect().top >= 0 && this.lockOneApiState == true && this.isRefreshDisabled == false) { this.params.page_num++; this.getapi(); this.lockOneApiState = false; } }, // 伪装数据请求 getDataList(params) { return new Promise( resolve => { let result = { code: 200, result: { video_list: this.dataList.splice(1 * params.page_num - 1, params.page_size) } }; setTimeout(() => { resolve(result); }, 1000); } ); } } }; </script> <style lang="scss" scoped> .refresh { padding: 0 20px 20px 20px; .content{ width: 100%; height: 320px; text-align: center; margin-top: 20px; background-color: cadetblue; font-size: 22px; } } </style>
到此这篇关于Vue+Vant实现下拉加载功能的文章就介绍到这了,更多相关Vue Vant下拉加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!