完全实现首页的三大框架基本功能

This commit is contained in:
2025-10-08 22:45:47 +08:00
parent 698f27372d
commit be7a53f61a
4 changed files with 153 additions and 373 deletions

View File

@@ -26,9 +26,7 @@
<el-carousel
class="carousel-container"
height="400px"
indicator-position="bottom"
autoplay
interval="5000"
arrow="always"
>
<el-carousel-item>
@@ -100,11 +98,62 @@
</el-card>
</div>
</div>
<div class="news-section">
<div class="section-header">
<h2>案例资源 <span class="en-title">Resource</span></h2>
<el-link class="more-btn">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(resource, index) in resourceList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="resource.imageUrl" alt="案例资源图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ resource.title }}</h3>
<p class="card-desc">{{ resource.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
<div class="news-section">
<div class="section-header">
<h2>社区服务 <span class="en-title">Community</span></h2>
<el-link class="more-btn">More</el-link>
</div>
<div class="news-cards">
<el-card
class="news-card"
v-for="(service, index) in communityList"
:key="index"
shadow="hover"
:body-style="{ padding: '0px' }"
>
<img :src="service.imageUrl" alt="社区服务图片" class="card-img">
<div class="card-content">
<h3 class="card-title">{{ service.title }}</h3>
<p class="card-desc">{{ service.desc }}</p>
<el-button type="text" class="detail-btn">
<el-icon><ArrowRight /></el-icon> 详情
</el-button>
</div>
</el-card>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
// **修复点1将所有用到的 Element Plus 组件一次性导入**
import { ref, onMounted } from 'vue';
import {
ElMenu,
ElMenuItem,
@@ -115,37 +164,111 @@ import {
ElButton,
ElIcon
} from 'element-plus';
// **修复点2从 @element-plus/icons-vue 导入图标**
import { ArrowRight } from '@element-plus/icons-vue';
// 导航菜单激活项
const activeIndex = ref('1');
const handleSelect = (index: string) => {
activeIndex.value = index;
// 可添加导航跳转逻辑
};
// 模拟新闻数据(实际项目可替换为接口请求)
const newsList = ref([
{
imageUrl: 'https://picsum.photos/300/200?random=10', // 随机图片占位
title: '健康设计与知识创新国际学术研讨会',
desc: '探索健康设计的新路径,引领知识创新的新范式,共同描绘人类健康的未来图景。'
},
{
imageUrl: 'https://picsum.photos/300/200?random=11',
title: '第二届中国研究生“美丽中国”创新设计大赛',
desc: '探索健康设计的新路径,引领知识创新的新范式,共同描绘人类健康的未来图景。'
},
{
imageUrl: 'https://picsum.photos/300/200?random=12',
title: '国家一流专业中期建设成果展',
desc: '探索健康设计的新路径,引领知识创新的新范式,共同描绘人类健康的未来图景。'
}
]);
</script>
// --- Data Structures ---
interface NewsItem {
imageUrl: string;
title: string;
desc: string;
}
interface Article {
id: number;
title: string;
cover: string;
excerpt: string;
}
// **修改点1: 为每个版块创建独立的响应式数组**
const newsList = ref<NewsItem[]>([]);
const resourceList = ref<NewsItem[]>([]);
const communityList = ref<NewsItem[]>([]);
// --- Utility Function ---
/**
* @description 将HTML字符串转换为纯文本
* @param htmlStr HTML字符串
* @returns 纯文本字符串
*/
function stripHtml(htmlStr: string): string {
if (!htmlStr) return '';
const doc = new DOMParser().parseFromString(htmlStr, 'text/html');
return doc.body.textContent || "";
}
// **修改点2: 创建一个通用的、可复用的 fetch 函数**
/**
* @description 根据主题从后端获取文章列表
* @param topic 文章主题 (e.g., "新闻", "案例资源")
* @returns 处理过的文章列表
*/
const fetchArticlesByTopic = async (topic: string): Promise<NewsItem[]> => {
try {
const response = await fetch('http://localhost:8080/api/articles/getarticle', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
page: 1,
size: 3, // 只请求需要的前3条数据
topic: topic
})
});
if (!response.ok) {
throw new Error(`HTTP error for topic ${topic}! status: ${response.status}`);
}
const data = await response.json();
if (data && Array.isArray(data.Article_list)) {
const articles: Article[] = data.Article_list;
return articles.map(article => {
const plainTextDesc = stripHtml(article.excerpt);
const truncatedDesc = plainTextDesc.length > 100
? plainTextDesc.substring(0, 100) + '...'
: plainTextDesc;
return {
imageUrl: article.cover,
title: article.title,
desc: truncatedDesc,
};
});
} else {
console.error(`API response for topic ${topic} is not in the expected format:`, data);
return []; // 返回空数组以防错误
}
} catch (error) {
console.error(`Failed to fetch articles for topic ${topic}:`, error);
return []; // 发生错误时返回空数组
}
};
// **修改点3: 在组件挂载时,并行获取所有版块的数据**
onMounted(async () => {
// 使用 Promise.all 来同时触发所有API请求提高加载效率
const [newsData, resourceData, communityData] = await Promise.all([
fetchArticlesByTopic('新闻'),
fetchArticlesByTopic('案例资源'),
fetchArticlesByTopic('社区服务')
]);
// 将获取到的数据赋值给对应的列表
newsList.value = newsData;
resourceList.value = resourceData;
communityList.value = communityData;
});
</script>
<style scoped>
.header-with-carousel {
width: 100%;
@@ -354,4 +477,4 @@ const newsList = ref([
grid-template-columns: 1fr; /* 手机:一行一个 */
}
}
</style>
</style>