新闻发布与列表
新闻发布与列表
学习目标
- 前端实现发布新闻页面,调用
/news/add接口。 - 前端首页调用
/news/page分页接口,展示表格。
操作步骤
步骤1:修改 api/news.js
全部替换为如下内容:
import request from '../utils/request'
export const getNewsPage = (page, size) => {
return request.get('/news/page', { params: { page, size } })
}
export const publishNews = (data) => {
return request.post('/news/add', data)
}
export const getNewsDetail = (id) => {
return request.get(`/news/${id}`)
}
export const updateNews = (id, data) => {
return request.put(`/news/${id}`, data)
}
export const deleteNews = (id) => {
return request.delete(`/news/${id}`)
}
export const likeNews = (id, likes) => request.patch(`/news/${id}`, { likes })
步骤2:修改 Home.vue(加载新闻列表)
替换template和script的内容,保留style中的内容,替换的内容如下:
<!-- src/views/Home.vue -->
<template>
<div class="home-container">
<!-- 固定头部 -->
<div class="header">
<h2>微头条首页</h2>
<div>欢迎,{{ userStore.username }}</div>
<button @click="logout">退出登录</button>
</div>
<!-- 可滚动的内容区域(发布区 + 新闻列表) -->
<div class="scroll-area">
<div class="content-wrapper">
<!-- 发布区域 -->
<div class="publish-area">
<button @click="goToPublish">+ 发布微头条</button>
</div>
<!-- 新闻列表 -->
<div class="news-list">
<div v-if="newsList.length === 0" class="empty">
暂无新闻,快去发布一条吧
</div>
<div v-for="item in newsList" :key="item.id" class="news-item">
<h3>{{ item.title }}</h3>
<div class="time">{{ item.time }}</div>
<div class="content">{{ item.content }}</div>
<div class="actions">
<button @click="homeViewDetail(item.id)">📚 查看详情</button>
<button @click="homeDeleteNews(item.id)">🗑 删除</button>
<button @click="homeLikeNews(item.id, item.likes)">💗 点赞 {{ item.likes }}</button>
</div>
</div>
</div>
</div>
</div>
<el-pagination v-model:current-page="pageNum" v-model:page-size="pageSize" :total="total"
@current-change="loadNews" layout="prev, pager, next" />
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
import { ref, onMounted, onUnmounted } from 'vue'
import { useUserStore } from '../stores/user'
import { getNewsPage, publishNews, getNewsDetail, updateNews, deleteNews, likeNews } from '../api/news'
import { ElMessage } from 'element-plus'
const router = useRouter()
const userStore = useUserStore()
const newsList = ref([])
const newTitle = ref('')
const newContent = ref('')
const loading = ref(false)
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const loadNews = async () => {
loading.value = true
try {
const res = await getNewsPage(pageNum.value, pageSize.value)
if (res.code === 200) {
newsList.value = res.data.records
total.value = res.data.total
}
} finally {
loading.value = false
}
}
const addNews = async () => {
if (!newTitle.value.trim() || !newContent.value.trim()) {
ElMessage.warning('标题和内容不能为空')
return
}
const newNews = {
title: newTitle.value,
content: newContent.value,
time: new Date().toLocaleString(),
likes: 0,
userId: 1
}
try {
await publishNews(newNews)
ElMessage.success('发布成功')
newTitle.value = ''
newContent.value = ''
loadNews()
} catch {
ElMessage.error('发布失败')
}
}
const homeDeleteNews = async (id) => {
try {
await deleteNews(id)
ElMessage.success('删除成功')
loadNews()
} catch {
ElMessage.error('删除失败')
}
}
const homeLikeNews = async (id, currentLikes) => {
try {
await likeNews(id, currentLikes + 1)
loadNews()
} catch {
ElMessage.error('点赞失败')
}
}
const homeViewDetail = (id) => {
router.push(`/detail/${id}`)
}
const goToPublish = () => {
router.push('/publish')
}
const logout = () => {
userStore.logout()
router.push('/login')
}
onMounted(() => {
loadNews()
document.body.style.overflow = 'hidden'
})
onUnmounted(() => {
document.body.style.overflow = ''
})
</script>
步骤3:创建发布新闻页面
- 右键
views文件夹,新建Publish.vue

目录结构:

-
Publish.vue中的代码:<!-- src/views/Publish.vue --> <template> <div class="publish-container"> <el-card> <h2>发布微头条</h2> <el-form :model="form" :rules="rules" ref="formRef" label-width="80px"> <el-form-item label="标题" prop="title"> <el-input v-model="form.title" placeholder="请输入标题" /> </el-form-item> <el-form-item label="内容" prop="content"> <el-input v-model="form.content" type="textarea" rows="8" placeholder="请输入内容" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handlePublish" :loading="submitting">发布</el-button> <el-button @click="$router.back()">取消</el-button> </el-form-item> </el-form> </el-card> </div> </template> <script setup> import { reactive, ref } from 'vue' import { useRouter } from 'vue-router' import { publishNews } from '../api/news' import { ElMessage } from 'element-plus' const router = useRouter() const formRef = ref(null) const submitting = ref(false) const form = reactive({ title: '', content: '' }) const rules = { title: [{ required: true, message: '请输入标题', trigger: 'blur' }], content: [{ required: true, message: '请输入内容', trigger: 'blur' }] } const handlePublish = async () => { if (!formRef.value) return await formRef.value.validate(async (valid) => { if (valid) { submitting.value = true try { const res = await publishNews(form) if (res.code === 200) { ElMessage.success('发布成功') router.push('/home') } else { ElMessage.error(res.message) } } finally { submitting.value = false } } }) } </script> <style scoped> .publish-container { max-width: 800px; margin: 40px auto; } </style>
步骤4:添加路由
-
在
src/router/index.js添加import Publish from '../views/Publish.vue' { path: '/publish', component: Publish, meta: { requiresAuth: true } }注意加上逗号,添加位置如下:

结束时的项目状态
- 首页显示新闻列表(分页)。
- 点击发布新闻,填写表单提交,成功后跳转首页,列表自动刷新。

浙公网安备 33010602011771号