新闻发布与列表
任务清单
前端实现发布新闻页面,调用 /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号