Appearance
vue3新闻管理系统
时间预计:30分钟
技术: vue3, vuex, elementplus, json-server
数据来源: json-server提供接口
作业要求:
项目运行
node版本>= 18.18.0
1.在当前项目目录的命令行启动json-server,一定要带上版本,最新的json-server功能有问题
shell
npm install -g json-server@0.17.4 # NPM
yarn global add json-server@0.17.4 # Yarn
pnpm add -g json-server@0.17.4 # PNPM
shell
npm run mock # NPM
yarn run mock # Yarn
启动vue项目
shellyarn run dev # Yarn npm run dev # NPM
项目截图
01-登陆页面
02-首页
03-新闻管理页面
04-用户管理页面
05-个人中心页面
06-404页面
重点代码解析
1.封装element-plus的表格组件为SimpleTable,简化操作
2.新闻的增删改查逻辑
新闻表格 NewsList.vue
新建文件src/view/newsManage/NewsList.vue
vue
<template>
<el-card>
<template #header>
<div>
<span>新闻列表</span>
<el-button class="button"
size="small"
@click="onAdd()"
type="primary">
创建新闻
</el-button>
<!-- 搜索功能 -->
<div class="inputArea">
<el-input v-model="keyWords.k" placeholder="请输入" clearable :style="{ width: '200px'}" @clear="clearFn"/>
<el-button
type="primary"
@click="searchFn">
<el-icon><Search /></el-icon>
搜索
</el-button>
</div>
</div>
</template>
<div class="table-container">
<simple-table
:columns="columns"
:tableData="state.list"
optionWidth="200"
@handleEdit="onEdit"
@handleDelete="onDelete"
>
<template #currentStatus="scope">
<div>
<el-tag type="success" v-if="scope.row.currentStatus == '0'">发布</el-tag>
<el-tag type="info" v-else>未发布</el-tag>
</div>
</template>
</simple-table>
</div>
<!--注册/修改用户对话框-->
<NewsModal ref="userModal" @add="addFetch" @edit="editFetch" :modalConfig="modalConfig"></NewsModal>
</el-card>
</template>
<script setup>
//注意:vue3.x组合式api,需要在<script>里面使用setup
import {ref,reactive,onMounted} from "vue";
import { ElMessage } from 'element-plus';
import NewsModal from './NewsModal.vue';
import SimpleTable from '@/components/base/Table/SimpleTable.vue'
//导入axios实例(从封装的http.js中导入)
import http from "@/util/http.js";
// 获取弹窗的dom
const userModal = ref(null)
const modalConfig = reactive({
title: '创建新闻',
option: 'add'
})
// 定义表格列
const columns = reactive([
{ prop: "title", label: "新闻标题", minWidth: 120 },
{ prop: "intro", label: "内容", minWidth: 120 },
{ prop: "author", label: "作者", minWidth: 120 },
{ prop: "currentStatus", label: "状态", minWidth: 120,isSlot:true },
]);
//使用一个reactive方法定义响应式对象
const state = reactive({
//数据列表
list:[],
listSearchBefore:[],
//临时保存选中的行索引
selectedIndex:-1,
})
//生命周期钩子
onMounted(() =>{
initTable()
})
const initTable = ()=>{
http.get("/news").then(res=>{
if(res.status === 200 || res.status === 201){
//更新表格
state.list = res.data;
state.listSearchBefore = res.data
}
}).catch(err=>{
console.log(err)
ElMessage.error('获取数据失败');
})
}
//响应注册按钮,打开注册对话框
const onAdd = ()=>{
modalConfig.title = "创建新闻"
modalConfig.option = "add"
userModal.value.open()
}
// 新增操作
const addFetch = async (formData)=>{
let res = await http.post("/news",formData)
if(res.status === 200 || res.status ===201 ){
// 操作成功
ElMessage({
message: "保存成功!",
type: "success"
});
//更新表格
state.list.push(formData);
}
}
// 编辑操作
const onEdit = ({index})=>{
modalConfig.title = "修改新闻"
modalConfig.option = "edit"
//获得要修改用户的信息
let user = state.list[index];
modalConfig.formData = user
userModal.value.open()
//临时保存选中的索引
state.selectedIndex = index;
}
const editFetch = (formData)=>{
http.put("/news/"+ formData.id,formData).then(res=>{
if (res.status === 200 || res.status === 201){
//操作成功
ElMessage({
message: "保存成功!",
type: "success"
});
//更新表格
state.list.splice(state.selectedIndex,1,res.data)
//重置selectedIndex
state.selectedIndex = -1;
//关闭对话框
}
})
}
//响应删除按钮
const onDelete = async ({index}) =>{
//删除被选中的数据
let id = state.list[index].id;
let res = await http.delete("/news/" + id)
if (res.status === 200 || res.status === 201){
ElMessage("删除成功");
// 刷新表格,删除起始下标为1,长度为1的一个值
state.list.splice(index, 1);
}
}
// 搜索功能
const keyWords = reactive({
k:""
})
const searchFn = ()=>{
if(keyWords.k== ''){
initTable();
return
}
console.log(state.list,state.listSearchBefore,keyWords.k)
let itemData = state.listSearchBefore.filter((p) => {
return p.title.indexOf(keyWords.k) !== -1
})
state.list = JSON.parse(JSON.stringify(itemData))
}
// 清除搜索条件
const clearFn = ()=>{
initTable()
}
</script>
<style scoped>
.table-container{
text-align: right;
}
</style>
新闻的新增与编辑弹窗 NewsModal.vue
新建文件src/view/newsManage/NewsModal.vue
vue
<template>
<div>
<el-dialog :title="modalConfig.title" v-model="dialogVisible">
<el-form ref="elForm" :model="formData" :rules="rules" size="default" label-width="100px">
<el-form-item label="新闻标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入新闻标题" :maxlength="20" show-word-limit clearable
:style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="新闻内容" prop="intro">
<el-input v-model="formData.intro" type="textarea" placeholder="请输入新闻内容" :maxlength="200"
show-word-limit :autosize="{minRows: 4, maxRows: 4}" :style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="formData.author" placeholder="请输入作者" clearable :style="{width: '100%'}">
</el-input>
</el-form-item>
<el-form-item label="发布状态" prop="currentStatus" required>
<el-switch v-model="formData.currentStatus" :active-value='0' :inactive-value='1'></el-switch>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
modalConfig:{
type: Object,
default: ()=>{
return{
title: '弹窗标题',
option: 'add'
}
}
}
},
data() {
return {
dialogVisible: false,
formData: {
title: undefined,
intro: "",
author: undefined,
currentStatus: 1,
},
rules: {
title: [{
required: true,
message: '请输入新闻标题',
trigger: 'blur'
}],
intro: [{
required: true,
message: '请输入新闻内容',
trigger: 'blur'
}],
author: [{
required: true,
message: '请输入作者',
trigger: 'blur'
}],
},
}
},
computed: {},
watch: {},
created() {},
mounted() {},
methods: {
// 打开弹窗
open() {
this.dialogVisible = true
// 编辑初始化
if(this.modalConfig.option==='edit'){
this.formData = this.modalConfig.formData
}
// 新增初始化
if(this.modalConfig.option==='add'){
// 初始化当前用户名
const userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
this.formData = {
title: undefined,
intro: "",
author: userInfo.userName,
currentStatus: 1,
}
}
},
close() {
this.dialogVisible = false
},
handelConfirm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// 新增操作
if(this.modalConfig.option==='add'){
// 设置新增用户id
this.formData.id = (new Date()).valueOf() + ''
// 返回结果
this.$emit('add', this.formData)
}
// 编辑操作
if(this.modalConfig.option==='edit'){
// 返回结果
this.$emit('edit', this.formData)
}
this.close()
})
},
}
}
</script>
<style>
</style>
3.404页面的路由匹配
极速大抄(获取源码)
直接拿项目源码
请关注微信公众号 技术成神
添加阿飞(微信号:jscsvip
)
提供源码与技术支持,保证服务满意