hookehuyr

feat(新闻详情页): 添加加载状态和错误处理

在新闻详情页中添加加载状态显示和错误处理逻辑
- 使用VanLoading组件显示加载状态
- 添加错误状态提示和返回按钮
- 重构数据获取逻辑,增加try-catch处理
......@@ -15,6 +15,7 @@ declare module 'vue' {
VanCell: typeof import('vant/es')['Cell']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanLoading: typeof import('vant/es')['Loading']
VanOverlay: typeof import('vant/es')['Overlay']
VideoPlayer: typeof import('./components/VideoPlayer.vue')['default']
}
......
<template>
<div class="page-container">
<!-- 内容区域 -->
<div class="content-container">
<!-- Loading状态 -->
<div class="loading-container" v-if="isLoading">
<van-loading size="24px" color="#8b4513">加载中...</van-loading>
</div>
<!-- 内容区域 - 只有加载完成且有数据时才显示 -->
<div class="content-container" v-else-if="!isLoading && article.title">
<!-- 文章头部 -->
<div class="article-header">
<h1 class="article-title">{{ article.title }}</h1>
......@@ -23,6 +28,15 @@
<div class="content-text" v-html="article.content"></div>
</div>
</div>
<!-- 加载失败或无数据时的提示 -->
<div class="error-container" v-else>
<div class="error-message">
<van-icon name="warning-o" size="48" color="#999" />
<p>文章加载失败或不存在</p>
<van-button type="primary" @click="$router.go(-1)">返回</van-button>
</div>
</div>
</div>
</template>
......@@ -43,42 +57,35 @@ const router = useRouter()
useTitle(() => '新闻详情');
// 文章数据
const article = ref({
id: 1,
title: '三坛大戒 | 护戒胜福田 成就最上因',
content: `
<p>为弘承世尊遗教,光大如来戒法,绍隆佛种,续佛慧命,经研究并报中国佛教协会批复同意(中佛会〔2025〕35号),由江苏省佛教协会主办,苏州市佛教协会、苏州市姑苏区佛教协会、苏州工业园区佛教协会协办,苏州西园戒幢律寺、苏州工业园区积善寺承办的传戒三坛大戒法会定于2025年10月15日至11月15日举办。</p>
<h3>天增上三学,以戒为首</h3>
<h3>佛灭度后,以戒为师</h3>
<p>《梵网经》云:"众生受佛戒,即入诸佛位。位同大觉已,真是诸佛子。"传戒法会,具称"千佛三坛大戒法会",三坛大戒是成就僧人最重要的增上缘仪式,谓授千佛共同所制戒。戒场分非同一般之法会场所,庄妙标有,无过之者。</p>
<p>今苏州西园戒幢律寺作为主戒场传戒三坛大戒,正值因时,其事庄严,此意成就道场通达。</p>
`,
author: '戒幢律寺编辑部',
publishDate: '2025-10-1',
viewCount: 2156,
likeCount: 156,
isLiked: false,
isCollected: false,
coverImage: 'https://images.unsplash.com/photo-1545558014-8692077e9b5c?w=800&h=600&fit=crop',
})
const article = ref({})
// 加载状态
const isLoading = ref(true)
// 组件挂载时加载数据
onMounted(async () => {
const articleId = route.params.id
const { code, data } = await getArticleDetailAPI({ i: articleId })
if (code) {
article.value = {
...data,
id: data.id,
title: data.post_title,
content: data.post_content,
publishDate: dayjs(data.post_date).format('YYYY-MM-DD HH:mm:ss'),
author: data.post_author,
coverImage: data.photo,
try {
const articleId = route.params.id
const { code, data } = await getArticleDetailAPI({ i: articleId })
if (code) {
let coverImage = data.file_list.photo ? data.file_list.photo.value : ''
article.value = {
...data,
id: data.id,
title: data.post_title,
content: data.post_content,
publishDate: dayjs(data.post_date).format('YYYY-MM-DD HH:mm:ss'),
author: data.post_author,
coverImage: coverImage,
}
} else {
Toast.fail('加载文章失败')
}
} catch (error) {
console.error('加载文章出错:', error)
Toast.fail('加载文章出错')
} finally {
// 无论成功还是失败,都结束loading状态
isLoading.value = false
}
})
</script>
......@@ -88,6 +95,19 @@ onMounted(async () => {
background: #f5f5f5;
}
.loading-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #f5f5f5;
z-index: 999;
}
.content-container {
background-color: #F2EBDB;
min-height: 100vh;
......@@ -171,4 +191,24 @@ onMounted(async () => {
.content-text :deep(p:last-child) {
margin-bottom: 0;
}
/* 错误状态样式 */
.error-container {
background-color: #F2EBDB;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.error-message {
text-align: center;
padding: 2rem;
}
.error-message p {
margin: 1rem 0;
color: #999;
font-size: 1rem;
}
</style>
......