vue2分页加载器实现

This commit is contained in:
WindowBird 2025-08-29 15:33:14 +08:00
parent 3dec91aacd
commit a79bd2c500
3 changed files with 293 additions and 23 deletions

View File

@ -10,6 +10,21 @@ export function getInstitutionalDetail(formedId) {
return get("/app/formed/formedDetail", { formedId });
}
export function getProjectSchedule(formedId) {
return get("/app/article/listFormed", { formedId });
// export function getProjectSchedule(formedId) {
// return get("/app/article/listFormed", { formedId });
// }
/**
* 获取建制数据列表
* @param {Object} params - 查询参数
* @param {number} params.pageNum - 页码
* @param {number} params.pageSize - 每页数量
* @returns {Promise} 返回项目进度数据
*/
export function getProjectSchedule(params = {}) {
const defaultParams = {
pageNum: 1,
pageSize: 2,
};
return get("/app/article/listFormed", { ...defaultParams, ...params });
}

View File

@ -0,0 +1,209 @@
/**
* 分页管理工厂函数 (带winB_前缀)
* @param {Object} options - 配置选项
* @param {Function} options.fetchData - 获取数据的API函数
* @param {Object} options.defaultParams - 默认查询参数
* @param {string} options.mode - 分页模式'loadMore' 'pager'
* @param {number} options.pageSize - 每页数量
* @returns {Object} Vue组件选项对象
*/
export function createPagination(options = {}) {
const {
fetchData,
defaultParams = {},
mode = "loadMore",
pageSize = 10,
} = options;
return {
data() {
return {
// 基础状态
winB_List: [],
winB_Loading: false,
winB_Error: null,
// 分页参数
winB_QueryParams: {
pageNum: 1,
pageSize,
...defaultParams,
},
// 分页信息
winB_Pagination: {
total: 0,
currentPage: 1,
pageSize,
totalPages: 0,
},
// 上拉加载相关
winB_NoMore: false,
};
},
computed: {
winB_HasData() {
return this.winB_List.length > 0;
},
winB_IsEmpty() {
return !this.winB_Loading && this.winB_List.length === 0;
},
winB_CanLoadMore() {
return mode === "loadMore" && !this.winB_NoMore && !this.winB_Loading;
},
},
methods: {
/**
* 获取数据
* @param {boolean} reset - 是否重置列表
*/
async winB_GetList(reset = false) {
if (this.winB_Loading) return;
if (reset) {
this.winB_List = [];
this.winB_QueryParams.pageNum = 1;
this.winB_NoMore = false;
}
this.winB_Loading = true;
this.winB_Error = null;
try {
const response = await fetchData(this.winB_QueryParams);
if (!response || response.code !== 200) {
throw new Error(response?.message || "获取数据失败");
}
const { rows = [], total = 0 } = response;
if (reset) {
this.winB_List = rows;
} else {
this.winB_List = [...this.winB_List, ...rows];
}
// 更新分页信息
this.winB_Pagination = {
total,
currentPage: this.winB_QueryParams.pageNum,
pageSize,
totalPages: Math.ceil(total / pageSize),
};
// 检查是否还有更多数据
if (mode === "loadMore") {
this.winB_NoMore =
this.winB_QueryParams.pageNum * pageSize >= total;
console.log(
`noMore状态: ${this.winB_NoMore}, 当前页: ${this.winB_QueryParams.pageNum}, 每页: ${pageSize}, 总数: ${total}`,
);
}
console.log(
`获取数据成功: 第${this.winB_QueryParams.pageNum}页,共${rows.length}`,
);
} catch (err) {
console.error("获取数据失败:", err);
this.winB_Error = err;
// 显示错误提示
if (typeof uni !== "undefined") {
uni.showToast({
title: "数据加载失败",
icon: "none",
});
}
} finally {
this.winB_Loading = false;
}
},
/**
* 刷新数据
*/
winB_Refresh() {
this.winB_GetList(true);
},
/**
* 加载下一页上拉加载模式
*/
winB_LoadMore() {
if (!this.winB_CanLoadMore) return 0;
this.winB_QueryParams.pageNum++;
this.winB_GetList();
},
/**
* 跳转到指定页分页器模式
* @param {number} page - 目标页码
*/
winB_GoToPage(page) {
if (
page < 1 ||
page > this.winB_Pagination.totalPages ||
page === this.winB_QueryParams.pageNum
) {
return;
}
this.winB_QueryParams.pageNum = page;
this.winB_GetList(true);
},
/**
* 重置分页状态
*/
winB_Reset() {
this.winB_List = [];
this.winB_Loading = false;
this.winB_Error = null;
this.winB_NoMore = false;
this.winB_QueryParams.pageNum = 1;
this.winB_Pagination = {
total: 0,
currentPage: 1,
pageSize,
totalPages: 0,
};
},
/**
* 更新查询参数
* @param {Object} newParams - 新的查询参数
*/
winB_UpdateParams(newParams) {
this.winB_QueryParams = {
...this.winB_QueryParams,
...newParams,
pageNum: 1, // 重置页码
};
this.winB_Reset();
this.winB_GetList();
},
/**
* 格式化日期
* @param {string} dateString - 日期字符串
* @returns {string} 格式化后的日期
*/
winB_FormatDate(dateString) {
if (!dateString) return "未知";
const date = new Date(dateString);
return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}`;
},
},
created() {
// 初始化时加载第一页数据
this.winB_GetList();
},
};
}

View File

@ -46,7 +46,7 @@
<view class="new-develop-container">
<text class="section-title">最新进展</text>
<view
v-for="item in listData"
v-for="item in winB_List"
:key="item.id"
class="constructionSituation"
>
@ -70,7 +70,10 @@
></image>
</view>
</view>
<view class="more">查看更多{{ listData.length }}条数据</view>
<view v-if="winB_NoMore === false" class="more" @click="loadMore"
>查看更多{{ remainingItems }}条进展
</view>
<view v-else class="more">到底了</view>
</view>
</view>
</view>
@ -84,8 +87,16 @@ import {
getInstitutionalDetail,
getProjectSchedule,
} from "../../api/institutionalStructure/institutionalStructureDetail";
import { createPagination } from "../../composables/winB_Pagination";
export default {
mixins: [
createPagination({
fetchData: getProjectSchedule,
mode: "loadMore",
pageSize: 2,
}),
],
components: {},
data() {
return {
@ -120,7 +131,7 @@ export default {
{
id: "18",
templeId: "12",
title: "施工情况02",
title: "施工情况01",
content: "<p>施工情况02施工情况02...</p>",
status: "1",
templeName: "寒山寺",
@ -137,6 +148,46 @@ export default {
createTime: "2025-07-09 13:50:57",
coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg",
},
{
id: "19",
templeId: "12",
title: "施工情况01232",
content: "<p>施工情况02施工情况02...</p>",
status: "1",
templeName: "寒山寺",
createTime: "2025-07-09 13:50:57",
coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg",
},
{
id: "19",
templeId: "12",
title: "施工情况01232",
content: "<p>施工情况02施工情况02...</p>",
status: "1",
templeName: "寒山寺",
createTime: "2025-07-09 13:50:57",
coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg",
},
{
id: "19",
templeId: "12",
title: "施工情况01232",
content: "<p>施工情况02施工情况02...</p>",
status: "1",
templeName: "寒山寺",
createTime: "2025-07-09 13:50:57",
coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg",
},
{
id: "19",
templeId: "12",
title: "施工情况01232",
content: "<p>施工情况02施工情况02...</p>",
status: "1",
templeName: "寒山寺",
createTime: "2025-07-09 13:50:57",
coverUrl: "https://api.ccttiot.com/IMG01-1751968117197.jpg",
},
],
};
},
@ -148,15 +199,14 @@ export default {
}
//
this.loadPageData();
this.winB_GetList();
},
methods: {
//
async loadPageData() {
try {
//
const [detailResponse, scheduleResponse] = await Promise.all([
const [detailResponse] = await Promise.all([
getInstitutionalDetail(this.formedId),
getProjectSchedule(this.formedId),
]);
//
@ -169,28 +219,13 @@ export default {
icon: "none",
});
}
//
if (scheduleResponse?.code === 200) {
console.log("123:", scheduleResponse.rows);
this.listData = scheduleResponse.rows;
} else {
console.warn("获取项目进度失败:", scheduleResponse?.message);
uni.showToast({
title: "获取进度失败",
icon: "none",
});
}
} catch (error) {
console.error("获取页面数据失败:", error);
uni.showToast({
title: "数据加载失败",
icon: "none",
});
//
// setTimeout(() => this.loadPageData(), 2000);
} finally {
//
this.loading = false;
}
},
@ -205,6 +240,17 @@ export default {
return formattedHtml;
},
loadMore() {
this.winB_LoadMore();
},
},
computed: {
remainingItems() {
return (
this.winB_Pagination.total -
this.winB_Pagination.currentPage * this.winB_Pagination.pageSize
);
},
},
};
</script>