vue3 骨架屏+上拉加载更多封装

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
    }
  • 代码演示
    – 用法
<div class="router_view" style="height:800px;overflow-y: auto;">
	<ListView 
        :list-data="data"  
        :bind-scroll-document="routerView" 
        :empty-item="emptyItem" 
        :finished="finished"
        v-model:loading="showLoading"
        v-model:error="showError"
        @load="requestData"
        v-slot="{ item }"
        >
          <div class="item row-center item-between">
                <img
                    class="item_pic"
                    :src="item.full_photo"
                />
                <div class="col center_info">
                    <span class="name">
                    	联系人: {{ item.concact_name }}
                    span>
                    <span class="time">
                    	填写时间: {{ item.collection_time }}
                   span>
                div>
                <router-link
                 :to="{ path: '/form', 
                 query: { mode: 'edit_draft',fileId:item.fileid }}"
                 class="edit_text" 
                 >编辑div>
        ListView>
     div>
<script lang='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 = () => {
      // 异步更新数据
      // 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,
    };
  },
});
</script>
  • 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 事件。

  • loading 和 finished 分别是什么含义?
    List 有以下五种状态,理解这些状态有助于你正确地使用 List 组件:

    1. init,初始化加载中,当loading为true且listData长度为0时,为init状态,此时显示骨架屏
    2. 非加载中,loading 为 false,此时会根据列表滚动位置判断是否触发 load 事件
    3. 加载中,loading 为 true,表示正在发送异步请求,此时不会触发 load 事件
    4. 加载完成,finished 为 true且listData长度不为0,此时不会触发 load 事件
    5. 暂无数据,finished为true,loading为false,finished 为true
      在每次请求完毕后,需要手动将 loading 设置为 false,表示加载结束

全部代码






你可能感兴趣的:(vue,vue,ts,css3)