上拉加载
文档指明List组件是瀑布流滚动加载,用于展示长列表。当列表即将滚动到底部时,会触发事件并加载更多列表项。
实际使用时,List组件能做的就是触发加载事件,加载更多列表项对应的代码还需要开发者编写。
html
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
:error.sync="error"
error-text="请求失败,点击重新加载"
@load="onLoad" >
<van-cell v-for="item in list" :key="item" :title="item" />
</van-list>
基础用法(引用自文档):
List 组件通过 loading
和 finished
两个变量控制加载状态,当组件滚动到底部时,会触发 load
事件并将 loading
设置成 true
。此时可以发起异步操作并更新数据,数据更新完毕后,将 loading
设置成 false
即可。若数据已全部加载完毕,则直接将 finished
设置成 true
即可。
我的理解:
List 组件通过 loading 和 finished 两个变量控制加载状态。
loading变量代表刷新状态,值为true时表示加载中,值为false时表示加载结束。
finished变量代表另一个状态:数据是否加载完毕。数据库中的数据总有穷尽,finished值为true时表示已经加载到最后一条,没有更多;值为false表示依旧能够加载新的数据。
代码示例
js
import { getList } from "@/api/demo"
export default {
data() {
list: [],
loading: false,
error: false,
finished: false,
pageNum: 0, // 初始请求第一页
pageSize: 5
}
methods: {
// 当组件滚动到底部时,会触发 `load` 事件
// 并将 `loading` 设置成 `true`。此时可以发起异步操作并更新数据
async onLoad() {
// 加1,表示加载下一页
this.pageNum++; // 初始请求第一页
try {
// 发送 ajax 请求获取后端数据
const { rows, total } = await getList({
pageNum: this.pageNum,
pageSize: this.pageSize
});
} catch() {
this.error: true,
this.pageNum--;
}
// 返回的数据格式为:该格式来源于`mybatis`的轻量级分页插件pageHelper
// {
// rows: [], // 所请求的数据列表
// total: 10, // 数据总条数
// }
// 将新数据添加在已展示数据的后面
this.list = [...this.list, ...rows]
// 加载状态结束
this.loading = false;
// 判断是否达到终点
if(this.list.length == total) {
this.finished = true;
}
}
}
}
下面是文档给出的示例代码,经过对比可以发现,主要需要编写的就是加载更多列表项对应的代码:
js
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);
},
},
};
关于List组件的更多信息,可参考文档:Vant 2 - List组件
下拉刷新
PullRefresh组件用于提供下拉刷新的交互操作。
基础用法(引用自文档):
下拉刷新时会触发 refresh
事件,在事件的回调函数中可以进行同步或异步操作,操作完成后将 v-model
设置为 false
,表示加载完成。
我的理解
通过下拉这个操作,告知系统需要重新加载数据,此时会触发refresh
事件,在此事件中需要将相关变量重置为初始状态然后发出Ajax请求。
List 组件可以与 PullRefresh 组件结合使用,实现下拉刷新的效果。
代码示例
html
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
:error.sync="error"
error-text="请求失败,点击重新加载"
@load="onLoad" >
<van-cell v-for="item in list" :key="item" :title="item" />
</van-list>
</van-pull-refresh>
js
import { getList } from "@/api/demo"
export default {
data() {
list: [],
loading: false,
error: false,
finished: false,
pageNum: 0, // 初始请求第一页
pageSize: 5,
refreshing: false,
}
methods: {
onRefresh() {
// 清空列表数据
this.finished = false;
// 重新加载数据
// 将 loading 设置为 true,表示处于加载状态
this.loading = true;
this.onLoad(); // 手动执行onLoad()
},
// 当组件滚动到底部时,会触发 `load` 事件
// 并将 `loading` 设置成 `true`。此时可以发起异步操作并更新数据
async onLoad() {
if (this.refreshing) {
this.pageNum = 0;
this.list = [];
this.refreshing = false;
}
// 加1,表示加载下一页
this.pageNum++; // 初始请求第一页
try {
// 发送 ajax 请求获取后端数据
const { rows, total } = await getList({
pageNum: this.pageNum,
pageSize: this.pageSize
});
} catch() {
this.error: true,
this.pageNum--;
}
// 返回的数据格式为:该格式来源于`mybatis`的轻量级分页插件pageHelper
// {
// rows: [], // 所请求的数据列表
// total: 10, // 数据总条数
// }
// 将新数据添加在已展示数据的后面
this.list = [...this.list, ...rows]
// 加载状态结束
this.loading = false;
// 判断是否达到终点
if(this.list.length == total) {
this.finished = true;
}
}
}
}
多tab场景
比如任务列表,分为已完成、未完成,此时点击tab需要进行列表的切换。
官方示例:
html
<van-tabs v-model="active">
<van-tab title="标签 1">内容 1</van-tab>
<van-tab title="标签 2">内容 2</van-tab>
<van-tab title="标签 3">内容 3</van-tab>
<van-tab title="标签 4">内容 4</van-tab>
</van-tabs>
为了只维护一组以list数组核心的相关变量,列表不能放在 van-tab 标签内部。
代码示例
html
<van-tabs v-model="active" @change="onChange">
<van-tab title="未完成" :name="1"></van-tab>
<van-tab title="已完成" :name="2"></van-tab>
</van-tabs>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
:error.sync="error"
error-text="请求失败,点击重新加载"
@load="onLoad" >
<!-- 如果已完成、未完成的列表项有不同的UI(一般都不一样) , -->
<!-- 可依据 this.active 使用 v-if 进行条件渲染 -->
<!-- 未完成列表 -->
<div v-if="active == 1 ">
<van-cell v-for="item in list" :key="item" :title="item" />
</div>
<!-- 已完成列表 -->
<div v-if="active == 2 ">
<van-cell v-for="item in list" :key="item" :title="item" />
</div>
</van-list>
</van-pull-refresh>
js
import { getYwcList, getWwcList } from "@/api/demo"
export default {
data() {
active: 1,
list: [],
loading: false,
error: false,
finished: false,
pageNum: 0, // 初始请求第一页
pageSize: 5,
refreshing: false,
}
methods: {
onChange() {
// 标签切换时,需要清空列表数据后重新加载数据
this.finished = false;
this.pageNum = 0;
this.list = [];
// 将 loading 设置为 true,表示处于加载状态
this.loading = true;
// 手动执行onLoad()
this.onLoad();
},
onRefresh() {
// 清空列表数据后
this.finished = false;
// 重新加载数据
// 将 loading 设置为 true,表示处于加载状态
this.loading = true;
this.onLoad(); // 手动执行onLoad()
},
// 当组件滚动到底部时,会触发 `load` 事件
// 并将 `loading` 设置成 `true`。此时可以发起异步操作并更新数据
async onLoad() {
if (this.refreshing) {
this.pageNum = 0;
this.list = [];
this.refreshing = false;
}
// 加1,表示加载下一页
this.pageNum++; // 初始请求第一页
try {
switch (this.active) {
case: 1:
// 发送 ajax 请求获取后端数据
const { rows, total } = await getWwcList({
pageNum: this.pageNum,
pageSize: this.pageSize
});
break;
case: 2:
// 发送 ajax 请求获取后端数据
const { rows, total } = await getYwcList({
pageNum: this.pageNum,
pageSize: this.pageSize
});
break;
}
} catch() {
this.error: true,
this.pageNum--;
}
// 返回的数据格式为:该格式来源于`mybatis`的轻量级分页插件pageHelper
// {
// rows: [], // 所请求的数据列表
// total: 10, // 数据总条数
// }
// 将新数据添加在已展示数据的后面
this.list = [...this.list, ...rows]
// 加载状态结束
this.loading = false;
// 判断是否达到终点
if(this.list.length == total) {
this.finished = true;
}
}
}
}
留言
若有错误之处,请评论区批评指正,感谢。