vue3 骨架屏+上拉加载更多封装
- 介绍
因业务需求要用到滚动加载,就用到了vant组件库里的List组件,然后突发奇想封装了个骨架屏进去,api和使用方法还有文档都参考了vant的list组件,不过没有参考源码,此组件是我第一次封装,比较贴合自身业务,所以不太符合需求的同学可以直接修改源码使用,感谢vant团队!vant的List组件地址 (https://vant-contrib.gitee.io/vant/v3/#/zh-CN/list)
提供骨架屏展示、瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,会触发事件并加载更多列表项。
- 效果
- 引入
import ListView from '@/components/list_view/list_view.vue'
components:{
ListView
}
- 代码演示
– 用法
文章图片
class="name">
联系人: {{ item.concact_name }}
class="time">
填写时间: {{ item.collection_time }}
编辑
='ts'>
import { defineComponent, reactive, toRefs } from "vue";
import ListView from "@/components/list_view/list_view.vue";
export default defineComponent({
name: "",
components: {
ListView,
},
setup() {
const state = reactive({
list: [],
showLoading: true,
showError: false,
finished: false
});
// 设置骨架屏所用到的数据模板,主要用于撑开span标签
const emptyItem = {
full_photo: "",
concact_name: "asdasd",
collection_time: "2021-3-3 15:23",
};
//绑定一个可滑动的容器,默认情况下是window,也就是浏览器的默认滑动
// 如果限定列表是在某一个元素内滑动,就需要把这个可滑动的元素传入ListView组件
// 用来绑定滑动事件,如果没有不传就好了
const routerView = document.querySelector(".router_view");
const requestData = https://www.it610.com/article/() => {
// 异步更新数据
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
setTimeout(() => {
for (let i = 0;
i < 10;
i++) {
state.list.push({
full_photo:"http://static.feidaojixie.com/machine/51271/full_photo/e9532332299e357ab815373a145f8ce2",
concact_name: "联系人" + (state.list.length + 1),
collection_time: "2021-3-3 15:23",
});
}
// 加载状态结束
state.showLoading = false;
// 数据全部加载完成
if (state.list.length >= 40) {
state.finished = true;
}
}, 3000);
};
return {
...toRefs(state),
emptyItem,
routerView,
requestData,
};
},
});
- API
- Props
参数
说明
类型
默认值
list-data
数据数组
Array
[]
bind-key
vue的for循环绑定的key
String,Function
默认值为index
v-model:loading
是否处于加载状态,加载过程中不触发 load 事件
Boolean
false
v-model:error
是否加载失败,加载失败后点击错误提示可
以重新触发 load 事件
boolean
false
finished
是否已加载完成,加载完成后不再触发 load 事件
Boolean
false
loading-text
加载过程中的提示文案
String
加载中…
finished-text
加载完成后的提示文案
String
没有更多了…
error-text
加载失败后的提示文案
String
加载失败了,点我重新加载
empty-text
数据为空时的提示文案
String
暂无数据
immediate-check
是否在初始化时立即执行滚动位置检查
Boolean
true
empty-item
设置骨架屏所用到的数据模板,主要用于撑开元素标签
Object
{}
bind-scroll-document
列表所在的可滑动的容器,默认为window
Object
window
- Events
事件名
说明
回调参数
load
滚动条与底部距离小于 offset 时触发
-
- Slots
名称
说明
default
列表内容
loading
自定义底部加载中提示
finished
自定义底部加载完成提示
error
自定义底部加载失败提示
empty
自定义列表数据为空提示
问题
- 骨架屏使用什么实现?
骨架屏是通过css样式给子项中的img和span、a标签设置背景色来实现的,所以需要传递 empty-item 参数来撑起列表元素的span和a标签,如果你还使用了其他标签,可以参考源码中css样式添加其他标签
- List 的运行机制是什么?
List 会监听浏览器或目标元素的滚动事件并计算列表的位置,当列表底部与可视区域的距离小于 offset 时,List 会触发一次 load 事件。
- 【vue|vue3 骨架屏+上拉加载更多封装】loading 和 finished 分别是什么含义?
List 有以下五种状态,理解这些状态有助于你正确地使用 List 组件:
- init,初始化加载中,当loading为true且listData长度为0时,为init状态,此时显示骨架屏
- 非加载中,loading 为 false,此时会根据列表滚动位置判断是否触发 load 事件
- 加载中,loading 为 true,表示正在发送异步请求,此时不会触发 load 事件
- 加载完成,finished 为 true且listData长度不为0,此时不会触发 load 事件
- 暂无数据,finished为true,loading为false,finished 为true
在每次请求完毕后,需要手动将 loading 设置为 false,表示加载结束
全部代码
{{ loadingText }}{{ emptyText }}{{ finshedText }}{{ errorText }}.list-view-init-view {
pointer-events: none;
}
.list-view-empty-view span,
.list-view-empty-view a {
color: rgba(0, 0, 0, 0) !important;
border-radius: 2px;
background: linear-gradient(
-45deg,
#999999 0%,
#777 25%,
#999999 50%,
#777 75%,
#999999 100%
);
animation: gradientBG 4s ease infinite;
background-size: 400% 400%;
}
/* [src=""],img:not([src])*/
.list-view-empty-view img {
content: url(./no_url.png);
background: linear-gradient(
-45deg,
#999999 0%,
#777 25%,
#999999 50%,
#777 75%,
#999999 100%
);
animation: gradientBG 4s ease infinite;
background-size: 400% 400%;
}
@keyframes gradientBG {
0% {
background-position: 100% 100%;
}
50% {
background-position: 0% 0%;
}
100% {
background-position: 100% 100%;
}}.fade-enter-active, .fade-leave-active {
transition: opacity .4s ease
}.fade-enter-from, .fade-leave-to {
opacity: 0.5
}.list-view-center{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px;
color: #777;
font-size: 15px;
}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- vue|Vue2.0+组件库总结
- uni-app|uniapp二维码识别
- 毕业设计|毕设项目 - 基于SSM的毕业设计管理系统(含源码+论文)
- VUE|VUE 跨域代理
- python|他来了!性能吊打 Node.js 和 Deno 的新一代 javaScript 运行时!
- 前端|越来越快的jsRuntime——Bun
- vue|vue环境搭建
- Vue项目导出|前端使用vue实现导出pdf
- vue|vue: 解决错误 RunScriptError: post install error, please remove node_modules before retry!