beehive/app/components/news/new.vue
2025-10-25 17:27:13 +08:00

236 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import {computed} from "vue";
import {useImageStyles} from '~/composables/useImageStyles';
// 组件属性
interface Props {
articleData: {
title: string
publishDate: string
category: string
content: string
prevArticle: {
title: string
url: string
}
nextArticle: {
title: string
url: string
}
}
loading: boolean
error: string
}
const props = withDefaults(defineProps<Props>(), {
articleData: () => ({
title: '',
publishDate: '',
category: '',
content: '',
prevArticle: {
title: '',
url: '#'
},
nextArticle: {
title: '',
url: '#'
}
}),
loading: true,
error: ''
})
// 使用传入的数据
const articleData = computed(() => props.articleData)
const loading = computed(() => props.loading)
const error = computed(() => props.error)
// 重新加载页面方法
const reloadPage = () => {
if (typeof window !== 'undefined') {
window.location.reload()
}
}
// 使用图片样式处理 composable
const {initImageStyles} = useImageStyles(
() => props.articleData?.content || '',
'.article-content',
{
maxWidth: '100%',
margin: '15px 5px',
display: 'block',
boxSizing: 'border-box'
}
)
onMounted(() => {
// 初始化图片样式处理
initImageStyles()
})
</script>
<template>
<view>
<section class="container mx-auto mt-20 px-4">
<!-- 加载状态 -->
<div v-if="loading" class="loading-container" style="text-align: center; padding: 50px;">
<div
class="loading-spinner"
style="border: 4px solid #f3f3f3; border-top: 4px solid #ff8200; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto;"/>
<p style="margin-top: 20px; color: #666;">正在加载文章...</p>
</div>
<!-- 错误提示 -->
<div v-else-if="error" class="error-container" style="text-align: center; padding: 50px; color: #ff6b6b;">
<p>{{ error }}</p>
<button
class="bg-primary mt-5 px-5 py-2.5 "
style=" color: white; border: none; border-radius: 4px; cursor: pointer;"
@click="reloadPage">
重新加载
</button>
</div>
<!-- 文章内容 -->
<div v-else class="row">
<div class="flex flex-col items-center">
<h2>{{ articleData?.title || '暂无标题' }}</h2>
<p id="label" style="border-bottom: 1px solid #ddd; margin-top: 20px;">
<span>{{ articleData?.publishDate || '暂无日期' }}</span>
<span class="pull-right"> 分类{{ articleData?.category || '暂无分类' }}</span>
</p>
<div class="article-content w-full" v-html="articleData?.content || '暂无内容'"/>
</div>
</div>
</section><!--/#blog-->
</view>
</template>
<style scoped>
/* 文章内容样式 */
.article-content {
margin-top: 20px;
line-height: 1.8;
font-size: 14px;
color: #333;
overflow: hidden; /* 防止内容溢出 */
word-wrap: break-word; /* 长单词换行 */
}
.article-content p {
margin-bottom: 15px;
}
/* 标签云样式 */
.tag-cloud li {
display: inline-block;
margin: 2px;
}
.tag-cloud a {
display: inline-block;
padding: 4px 8px;
background-color: #f5f5f5;
color: #666;
text-decoration: none;
border-radius: 3px;
font-size: 12px;
transition: all 0.3s ease;
}
.tag-cloud a:hover {
background-color: #ff8200;
color: #fff;
}
/* 推荐文章样式 */
.sy_news ul li {
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.sy_news ul li:last-child {
border-bottom: none;
}
.sy_news ul li a {
color: #333;
text-decoration: none;
font-size: 13px;
line-height: 1.4;
display: block;
transition: color 0.3s ease;
}
.sy_news ul li a:hover {
color: #ff8200;
}
.sy_news ul li a span {
color: #999;
font-size: 12px;
}
/* 上一篇下一篇样式 */
.nextorpre {
display: flex;
justify-content: space-between;
align-items: center;
}
.nextorpre li {
list-style: none;
margin: 0;
}
.nextorpre a {
color: #ff8200;
text-decoration: none;
}
.nextorpre a:hover {
text-decoration: underline;
}
/* 加载动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 加载状态样式 */
.loading-container {
min-height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* 错误状态样式 */
.error-container {
min-height: 200px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>