pager.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { computed, ref } from "vue";
  2. import { assign, parse } from "../utils";
  3. import { useListView, type ClListViewItem } from "@/uni_modules/cool-ui";
  4. // 分页参数类型
  5. type Pagination = {
  6. page: number; // 当前页码
  7. size: number; // 每页数量
  8. total: number; // 总数量
  9. };
  10. // 分页响应数据类型
  11. type PagerResponse = {
  12. list: UTSJSONObject[]; // 列表数据
  13. pagination: Pagination; // 分页信息
  14. };
  15. // 分页回调函数类型
  16. type PagerCallback = (params: UTSJSONObject) => Promise<UTSJSONObject>;
  17. // 分页器类
  18. export class Pager {
  19. public page = 1; // 当前页码
  20. public size = 20; // 每页数量
  21. public total = 0; // 总数量
  22. public list = ref<UTSJSONObject[]>([]); // 列表数据
  23. public loading = ref(false); // 加载状态
  24. public refreshing = ref(false); // 刷新状态
  25. public finished = ref(false); // 是否加载完成
  26. public params = {} as UTSJSONObject; // 请求参数
  27. public cb: PagerCallback | null = null; // 回调函数
  28. // 构造函数
  29. constructor(cb: PagerCallback) {
  30. this.cb = cb;
  31. }
  32. // 完成加载
  33. done() {
  34. this.loading.value = false;
  35. }
  36. // 清空数据
  37. clear() {
  38. this.list.value = [];
  39. this.finished.value = false;
  40. this.refreshing.value = false;
  41. this.loading.value = false;
  42. }
  43. // 刷新数据
  44. public refresh = async (params: UTSJSONObject): Promise<UTSJSONObject> => {
  45. return new Promise((resolve, reject) => {
  46. // 合并参数
  47. this.params = assign(this.params, params);
  48. // 构建请求参数
  49. const data = {
  50. page: this.page,
  51. size: this.size,
  52. ...this.params
  53. };
  54. // 设置加载状态
  55. this.loading.value = true;
  56. // 发起请求
  57. this.cb!(data)
  58. .then((res) => {
  59. // 解析响应数据
  60. const { list, pagination } = parse<PagerResponse>(res)!;
  61. // 更新分页信息
  62. this.page = pagination.page;
  63. this.size = pagination.size;
  64. this.total = pagination.total;
  65. // 更新加载完成状态
  66. this.finished.value = this.list.value.length >= this.total;
  67. // 更新列表数据
  68. if (data.page == 1) {
  69. this.list.value = [...list];
  70. } else {
  71. this.list.value.push(...list);
  72. }
  73. resolve(res);
  74. })
  75. .catch((err) => {
  76. reject(err);
  77. })
  78. .finally(() => {
  79. this.loading.value = false;
  80. });
  81. });
  82. };
  83. // 加载更多数据
  84. public loadMore = () => {
  85. if (this.loading.value || this.finished.value) {
  86. return;
  87. }
  88. this.refresh({
  89. page: this.page + 1
  90. });
  91. };
  92. // 列表视图数据
  93. public listView = computed<ClListViewItem[]>(() => {
  94. return useListView(this.list.value);
  95. });
  96. }
  97. // 创建分页器实例
  98. export const usePager = (cb: PagerCallback): Pager => {
  99. return new Pager(cb);
  100. };