hookehuyr

refactor: 迁移所有剩余页面到 LoadMoreList 组件

- message 页面:添加下拉刷新功能
- product-center 页面:保留搜索、tabs、计划书弹窗
- material-list 页面:保留分类缓存、搜索防抖
- search 页面:保留双列表、自动 tab 切换、三种状态

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This diff is collapsed. Click to expand it.
<!--
* @Date: 2026-02-08
* @Description: 我的消息页 - 使用 LoadMoreList 组件重构版本
-->
<template>
<view class="min-h-screen bg-[#F9FAFB] pb-safe">
<LoadMoreList
:list="currentList"
:page="currentPage"
:page-size="pageSize"
:has-more="hasMore"
:loading="loading"
:loading-more="loadingMore"
:enable-pull-down-refresh="true"
key-field="id"
@load-more="handleLoadMore"
@refresh="handleRefresh"
>
<!-- 头部 -->
<template #header>
<NavHeader title="我的消息" />
</template>
<!-- 列表区域 -->
<view class="p-4">
<template v-if="messageList.length > 0">
<!-- 列表项 -->
<template #item="{ item }">
<view
v-for="item in messageList"
:key="item.id"
class="bg-white rounded-xl p-4 mb-3 shadow-sm active:opacity-70 transition-opacity"
class="message-item bg-white rounded-xl p-4 mb-3 shadow-sm active:opacity-70 transition-opacity"
@tap="handleItemClick(item)"
>
<view class="flex justify-between items-start mb-2">
......@@ -26,29 +41,20 @@
{{ item.intro || item.content || '暂无简介' }}
</view>
</view>
<!-- 加载更多/没有更多 -->
<view class="py-4 text-center text-[24rpx] text-gray-400">
<text v-if="loading">加载中...</text>
<text v-else-if="!hasMore">没有更多了</text>
<text v-else>上拉加载更多</text>
</view>
</template>
<!-- 空状态 -->
<nut-empty
v-else-if="!loading && messageList.length === 0"
description="暂无消息"
image="empty"
/>
</view>
</view>
<template #empty>
<nut-empty description="暂无消息" image="empty" />
</template>
</LoadMoreList>
</template>
<script setup>
import { ref } from 'vue'
import { useLoad, usePullDownRefresh, useReachBottom, stopPullDownRefresh } from '@tarojs/taro'
import { useLoad } from '@tarojs/taro'
import { useGo } from '@/hooks/useGo'
import LoadMoreList from '@/components/LoadMoreList'
import NavHeader from '@/components/NavHeader.vue'
import { myListAPI } from '@/api/news'
import { mockMessageListAPI } from '@/utils/mockData'
......@@ -58,91 +64,165 @@ const USE_MOCK_DATA = process.env.NODE_ENV === 'development'
const go = useGo()
const messageList = ref([])
const page = ref(1)
const limit = ref(10)
/**
* 当前列表数据
* @type {Ref<Array<any>>}
*/
const currentList = ref([])
/**
* 当前页码(从1开始)
* @type {Ref<number>}
*/
const currentPage = ref(1)
/**
* 每页数量
* @type {number}
*/
const pageSize = 10
/**
* 是否还有更多数据
* @type {Ref<boolean>}
*/
const hasMore = ref(true)
const loading = ref(false)
/**
* @description 加载消息列表
* @param {boolean} refresh 是否刷新
* 首次加载状态
* @type {Ref<boolean>}
*/
const fetchMessageList = async (refresh = false) => {
if (loading.value) return
const loading = ref(false)
if (refresh) {
page.value = 1
hasMore.value = true
} else if (!hasMore.value) {
return
}
/**
* 加载更多状态
* @type {Ref<boolean>}
*/
const loadingMore = ref(false)
/**
* 获取消息列表
*
* @param {Object} params - 请求参数
* @param {number} params.page - 页码(从1开始)
* @param {number} params.limit - 每页数量
* @param {boolean} isLoadMore - 是否为加载更多
* @returns {Promise<void>}
*/
const fetchMessageList = async (params = {}, isLoadMore = false) => {
try {
// 如果是加载更多,使用 loadingMore 状态,否则使用 loading 状态
if (isLoadMore) {
loadingMore.value = true
} else {
loading.value = true
}
try {
console.log('[Message] 请求参数:', params)
console.log('[Message] 使用 Mock 数据:', USE_MOCK_DATA)
// 根据开关选择使用真实 API 或 Mock 数据
const res = USE_MOCK_DATA
? await mockMessageListAPI({
page: page.value,
limit: limit.value
})
: await myListAPI({
page: page.value,
limit: limit.value
})
if (res.code === 1) {
const list = res.data?.list || []
if (refresh) {
messageList.value = list
? await mockMessageListAPI(params)
: await myListAPI(params)
if (res.code === 1 && res.data) {
console.log('[Message] 数据:', res.data)
// 处理列表数据
if (res.data.list?.length) {
const listData = res.data.list
if (isLoadMore) {
// 加载更多:追加数据
currentList.value = [...currentList.value, ...listData]
} else {
messageList.value = [...messageList.value, ...list]
// 首次加载或刷新:替换数据
currentList.value = listData
}
if (list.length < limit.value) {
// 判断是否还有更多数据
// 如果返回的数据量少于请求的量,说明没有更多了
hasMore.value = listData.length >= params.limit
} else {
// 没有数据了
if (isLoadMore) {
hasMore.value = false
} else {
page.value++
currentList.value = []
}
}
} else {
console.error('[Message] API 返回错误:', res.msg)
}
} catch (err) {
console.error('获取消息列表失败:', err)
} catch (error) {
console.error('[Message] 获取消息列表失败:', error)
} finally {
if (isLoadMore) {
loadingMore.value = false
} else {
loading.value = false
if (refresh) {
stopPullDownRefresh()
}
}
}
/**
* @description 跳转到详情页
* @param {Object} item 消息对象
* 页面加载时获取数据
*/
const handleItemClick = (item) => {
go('/pages/message-detail/index', { id: item.id })
}
useLoad(async (options) => {
console.log('[Message] 页面参数:', options)
// 页面加载
useLoad(() => {
fetchMessageList(true)
})
// 重置分页状态
currentPage.value = 1
hasMore.value = true
// 下拉刷新
usePullDownRefresh(() => {
fetchMessageList(true)
// 获取消息列表
await fetchMessageList({ page: 1, limit: pageSize })
})
// 上拉加载更多
useReachBottom(() => {
fetchMessageList()
})
/**
* 处理加载更多事件
*
* @param {number} page - 下一页页码
* @returns {Promise<void>}
*/
const handleLoadMore = async (page) => {
console.log('[Message] 加载更多,页码:', page)
// 更新页码
currentPage.value = page
// 加载下一页数据
await fetchMessageList(
{ page: page, limit: pageSize },
true // 标记为加载更多
)
}
/**
* 处理下拉刷新事件
*/
const handleRefresh = async () => {
console.log('[Message] 下拉刷新')
// 重置分页状态
currentPage.value = 1
hasMore.value = true
// 刷新数据
await fetchMessageList({ page: 1, limit: pageSize })
}
/**
* 跳转到详情页
*
* @param {Object} item - 消息对象
*/
const handleItemClick = (item) => {
go('/pages/message-detail/index', { id: item.id })
}
</script>
<style lang="less">
/* Scoped styles if needed */
/* LoadMoreList 组件已内置样式,此处无需额外样式 */
</style>
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.