横幅海报
前言
前六天的开发工作完成了项目的基础架构、首页开发、文章列表页面、文章详情页面、公共组件抽离、交互优化和数据动态化。第七天的开发工作将重点关注横幅海报模块的动态化实现,进一步提升开发效率和完善功能模块。
编辑
一、横幅海报模块动态化
1.1 需求分析
横幅海报模块需要从 yucms_banner 表中动态获取数据,而不是使用静态数据。具体需求如下:
- 获取
banner_status为 1 的横幅(启用状态) - 按
update_time降序排序,取前 3 条 - 图片地址从
image_url字段获取 - 标题从
title字段获取 - 链接地址从
link_url字段获取 - 根据
iz_blank字段判断跳转方式(0=当前窗口,1=新窗口)
1.2 创建 Banner API 文件
在 src/api/banner.ts 中创建 Banner 相关的 API 函数:
import { defHttp } from '../utils/http/axios';
import { Api } from '../utils/http/axios';
export const getBannerList = (params?: any) => {
return defHttp.get({
url: Api.GetArticleList,
params: {
...params,
bannerStatus: '1',
pageSize: 3,
column: 'updateTime',
order: 'desc'
}
});
};
1.3 修改 Home.vue 横幅模块
在 Home.vue 中导入 API 函数并添加数据获取逻辑:
import { getBannerList } from '../api/banner';
// 横幅数据
const banners = ref([]);
// 获取横幅数据
async function fetchBanners() {
try {
const response = await getBannerList();
if (response.success && response.result) {
banners.value = response.result.records || [];
} else {
banners.value = [];
}
} catch (error) {
console.error('获取横幅数据失败:', error);
banners.value = [];
}
}
// 组件挂载时执行
onMounted(() => {
fetchBanners();
});
1.4 动态渲染横幅模板
使用 v-for 指令动态渲染横幅数据:
<div v-for="(banner, index) in banners" :key="banner.id" :class="['banner-slide', index === 0 ? 'active' : '']" :data-slide="index">
<div class="absolute inset-0">
<img :src="getImageUrl(banner.imageUrl)" :alt="banner.title" class="w-full h-full object-cover" />
<div class="absolute inset-0 bg-gradient-to-r from-black/70 via-black/40 to-transparent"></div>
</div>
<div class="relative h-full flex items-end pb-8">
<div class="container mx-auto px-8 md:px-16 lg:px-20">
<a :href="banner.linkUrl" :target="banner.izBlank === '1' ? '_blank' : '_self'" ...>
{{ banner.title }}
</a>
</div>
</div>
</div>
1.5 数据字段映射
| 数据库字段 | 前端使用 | 说明 |
|---|---|---|
image_url | banner.imageUrl | 图片地址 |
title | banner.title | 标题 |
link_url | banner.linkUrl | 跳转链接 |
iz_blank | banner.izBlank | 是否新窗口打开 |
banner_status | 过滤条件 | 状态(1启用) |
update_time | 排序字段 | 更新时间降序 |
二、内部链接路由处理
2.1 问题分析
横幅海报模块使用普通的 <a> 标签作为链接,当 iz_blank 为 0 时在当前窗口打开。但这种方式会导致页面刷新,丢失 Vue 组件状态,Header 和 Footer 也会重新渲染。
2.2 解决方案
使用 Vue Router 的 router-link 组件实现内部链接的客户端导航:
<!-- 内部链接使用 router-link -->
<router-link
v-if="banner.linkUrl && banner.linkUrl.startsWith('/') && banner.izBlank !== '1'"
:to="banner.linkUrl"
class="inline-flex items-center gap-2 px-6 py-2.5 text-sm font-semibold rounded-lg shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl"
style="background-color: #3b82f6; color: #0f172a;">
{{ banner.title }}
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path></svg>查看详情
</router-link>
<!-- 新窗口打开或外部链接使用普通 a 标签 -->
<a
v-else
:href="banner.linkUrl"
:target="banner.izBlank === '1' ? '_blank' : '_self'"
...>
{{ banner.title }}
</a>
2.3 逻辑说明
| 条件 | 使用组件 | 行为 |
|---|---|---|
linkUrl 以 / 开头且 izBlank !== '1' | router-link | 客户端导航,保留 Header/Footer |
izBlank === '1' 或外部链接 | <a> 标签 | 新窗口打开或页面跳转 |
三、图片路径统一修复
3.1 问题描述
Home.vue 和 ArticleDetail.vue 中的 getImageUrl 函数使用了不同的路径前缀:
- Home.vue 使用
/jeecgboot(不带横杠) - ArticleDetail.vue 使用
/jeecg-boot(带横杠)
由于项目的 Vite 代理配置使用的是 /jeecgboot,导致 ArticleDetail.vue 中的图片无法正确加载。
3.2 解决方案
统一所有页面中 getImageUrl 函数的路径前缀为 /jeecgboot:
function getImageUrl(imagePath) {
if (!imagePath) return null;
// 检查是否已经是完整URL
if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
return imagePath;
}
// 检查是否以/开头
if (imagePath.startsWith('/')) {
// 对于以/开头的路径,添加 /jeecgboot 前缀(与代理配置保持一致)
return `/jeecgboot${imagePath}`;
} else {
// 对于相对路径(如 temp/xxx.png 或 uploads/2024/03/xxx.jpg)
// 直接添加 /jeecgboot 前缀(与代理配置保持一致)
return `/jeecgboot/${imagePath}`;
}
}
3.3 Vite 代理配置
确保 vite.config.js 中的代理配置与图片路径处理保持一致:
server: {
port: 3001,
proxy: {
'/jeecgboot': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^/jeecgboot/, '/jeecg-boot')
}
}
}
四、总结
第七天的开发工作主要完成了以下内容:
- 横幅海报模块动态化:从
yucms_banner表动态获取数据,支持启用状态过滤和排序 - 内部链接路由处理:使用
router-link替代<a>标签实现客户端导航,保留页面状态 - UI 细节优化:横幅海报按钮位置调整、热门文章阅读数量显示
这些改进进一步提升了项目的开发效率和用户体验,为后续的功能完善奠定了基础。