feat: 实现前后端数据交互功能

- 添加axios API服务模块,封装所有后端接口调用
- 修改各视图组件,移除模拟数据,改为从后端API获取真实数据
- 更新文章、留言板等页面,支持后端数据渲染
- 添加README_API.md文档,说明API调用方式
- 升级axios依赖版本至1.12.2
This commit is contained in:
qingfeng1121
2025-10-11 13:32:06 +08:00
parent 4fe6add803
commit 07d3159b08
9 changed files with 563 additions and 203 deletions

86
src/axios/api.js Normal file
View File

@@ -0,0 +1,86 @@
import axios from 'axios'
// 创建axios实例
const service = axios.create({
baseURL: 'http://localhost:8080/api', // api的base_url
timeout: 3000, // 请求超时时间
headers: {
'Content-Type': 'application/json'
}
// withCredentials: true, // 跨域请求时是否需要使用凭证
})
// 请求拦截器 - 添加认证token
service.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器 - 统一处理响应
service.interceptors.response.use(
response => {
// 检查响应是否成功
if (response.data && response.data.success) {
return response.data
} else {
// 处理业务错误
return Promise.reject(new Error(response.data?.message || '请求失败'))
}
},
error => {
// 处理HTTP错误
console.error('API请求错误:', error)
// 可以在这里添加全局错误处理,如显示错误提示
return Promise.reject(error)
}
)
// 文章相关API
export const articleAPI = {
// 获取所有文章
getAllArticles: () => service.get('/articles'),
// 获取单篇文章
getArticleById: (id) => service.get(`/articles/${id}`),
// 根据分类获取文章
getArticlesByCategory: (categoryId) => service.get(`/articles/category/${categoryId}`),
// 获取热门文章
getPopularArticles: () => service.get('/articles/popular'),
// 创建文章
createArticle: (articleData) => service.post('/articles', articleData),
// 更新文章
updateArticle: (id, articleData) => service.put(`/articles/${id}`, articleData),
// 删除文章
deleteArticle: (id) => service.delete(`/articles/${id}`)
}
// 留言相关API
export const messageAPI = {
// 获取所有留言
getAllMessages: () => service.get('/messages'),
// 获取单条留言
getMessageById: (id) => service.get(`/messages/${id}`),
// 根据文章ID获取留言
getMessagesByArticleId: (articleId) => service.get(`/messages/article/${articleId}`),
// 获取根留言
getRootMessages: () => service.get('/messages/root'),
// 根据父留言ID获取回复
getRepliesByParentId: (parentId) => service.get(`/messages/parent/${parentId}`),
// 根据昵称搜索留言
searchMessagesByNickname: (nickname) => service.get(`/messages/search?nickname=${nickname}`),
// 获取文章评论数量
getMessageCountByArticleId: (articleId) => service.get(`/messages/count/${articleId}`),
// 创建留言
saveMessage: (messageData) => service.post('/messages', messageData),
// 删除留言
deleteMessage: (id) => service.delete(`/messages/${id}`)
}
export default service

View File

@@ -105,10 +105,7 @@ const handleSelect = (key: string) => {
*/
const updatePageState = (url: string) => {
classhero.value = url !== '/:type';
console.log("当前路径是:"+url);
classnonsenset.value = url == '/nonsense';
console.log( classnonsenset.value);
};
/**
@@ -154,14 +151,12 @@ const handleScroll = () => {
isconts.value = true;
isScrollingleftmodlue.value = true;
}
console.log("好耶滚动了");
};
/**
* 添加滚动监听
*/
const addScrollListener = () => {
console.log("添加滚动监听");
window.addEventListener('scroll', handleScroll);
};
@@ -169,7 +164,6 @@ const addScrollListener = () => {
* 移除滚动监听
*/
const removeScrollListener = () => {
console.log("移除滚动监听");
window.removeEventListener('scroll', handleScroll);
};
@@ -184,7 +178,6 @@ const handleResize = () => {
isScrollingleftmodlue.value = true;
classnonsenset.value = false;
isconts.value = true;
// removeScrollListener();
} else {
windowwidth.value = true;

View File

@@ -5,11 +5,11 @@
</div>
<div class="post_content">
<div v-for="(items, index) in datas" style=" padding: 20px;">
<h2>{{ items[index].title }}</h2>
<h2>{{ items[index] }}</h2>
<span class="badge badge-primary">{{ contentsum(items) }}</span>
<ul class="pcont_ul">
<li class="pcont_li" v-for="item in items">
<a class="btn" @click="btnonclick(item.contentid)"><kbd>{{ item.content }}</kbd></a> ({{ item.sum }})
<a class="btn" @click="btnonclick(item.typeid)"><kbd>{{ item.content }}</kbd></a> ({{ item.sum }})
</li>
</ul>
</div>
@@ -18,12 +18,26 @@
</template>
<script setup>
import { useRouter } from 'vue-router'
import { articleAPI } from '@/axios/api'
import { ref, onMounted } from 'vue'
const router = useRouter()
const btnonclick = (contentid) => {
const datas = ref([])
console.log("获取文章列表")
onMounted(() => {
articleAPI.getAllArticles().then(res => {
datas.value = res.data
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("finally")
})
})
const btnonclick = (typeid) => {
router.push({
path: '/:type',
query: {
type: contentid
type: typeid
}
})
}
@@ -34,59 +48,6 @@ const contentsum = (items) => {
}
return nums
}
const datas = [
// 学习模块
[
{
title: '学习',
contentid: '1',
content: '算法',
sum: 1,
},
{
title: '学习',
contentid: '2',
content: '前端',
sum: 1,
},
{
title: '学习',
contentid: '3',
content: '后端',
sum: 1,
},
{
title: '学习',
contentid: '4',
content: 'Java',
sum: 1,
},
],
// 生活模块
[
{
title: '生活',
contentid: '1',
content: '生活',
sum: 1,
},
{
title: '生活',
contentid: '2',
content: '书',
sum: 1,
},
{
title: '生活',
contentid: '2',
content: '书',
sum: 1,
}
]
]
</script>
<style>
.header {

View File

@@ -1,15 +1,31 @@
<template>
<div id="allstyle">
<div class="header">
<h1>文章内容页面</h1>
<h1>{{ article.title }}</h1>
</div>
<div class="article-content">
<p>{{ article.content }}</p>
</div>
<p>通过传来的{{ urls }}向服务器发送请求获取相关文章的链接</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router';
import { articleAPI } from '@/axios/api'
import { ref, onMounted } from 'vue'
const article = ref({})
const urls = useRoute().query
// 从后端获取文章详情
onMounted(() => {
articleAPI.getArticleById(urls.articleid).then(res => {
article.value = res.data
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("finally")
})
})
</script>
<style>
</style>

View File

@@ -5,7 +5,7 @@
class="article-card"
v-for="item in datas"
:key="item.title + item.publishedAt"
@click="aericleClick(item.aur)"
@click="aericleClick(item.articleid)"
>
<h2>{{ item.title }}</h2>
<el-text class="mx-1">{{ item.author }}</el-text>
@@ -18,8 +18,21 @@
<script setup>
import { useRouter } from 'vue-router'
import { articleAPI } from '@/axios/api'
import { ref, onMounted } from 'vue'
const router = useRouter()
const datas = ref([])
console.log("获取文章列表")
onMounted(() => {
articleAPI.getAllArticles().then(res => {
datas.value = res.data
console.log(res.data)
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("finally")
})
})
// 跳转到文章详情
const aericleClick = (aur) => {
router.push({
@@ -27,104 +40,6 @@ const aericleClick = (aur) => {
query: { url: aur }
})
}
// 文章数据
const datas = [
{
title: '测试1',
author: '这是文章模块测试',
aur: '链接',
mg: '11',
publishedAt: '2016-04-10'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
]
</script>
<style scoped>

View File

@@ -13,7 +13,7 @@
<!-- 评论内容 -->
<div class="message-item-top">
<div class="message-nickname">{{ msg.nickname }}</div>
<div class="message-time">{{ msg.time }}</div>
<div class="message-time">{{ msg.createdAt }}</div>
</div>
<div class="message-content">{{ msg.content }}</div>
<!-- 回复按钮 -->
@@ -86,39 +86,21 @@
</template>
<script setup>
import { reactive, ref } from 'vue'
import { reactive, ref, onMounted } from 'vue'
import { messageAPI } from '@/axios/api'
const message_all = ref({})
const hoverId = ref(null)
const messages = ref([
{
id: 1,
nickname: 'A',
content: '这里是A',
time: '2025-09-26 10:00',
replies: [
{
id: 4,
nickname: 'B',
content: 'A我来回复你',
time: '2025-09-26 10:20'
}
]
},
{
id: 2,
nickname: 'B',
content: '这里是B',
time: '2025-09-26 10:05',
replies: []
},
{
id: 3,
nickname: 'C',
content: '这里是C',
time: '2025-09-26 10:10',
replies: []
}
])
const messages = ref([])
// 从后端获取留言列表
onMounted(() => {
messageAPI.getAllMessages().then(res => {
messages.value = res.data
}).catch(err => {
console.log(err)
}).finally(() => {
console.log("finally")
})
})
const form = reactive({
replyid: null,