后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0926)
十四、文章分类添加编辑 [element-plus 弹层]
Git仓库:https://gitee.com/msyycn/vue3-hei-ma.git
点击显示弹层
- 准备弹层
const dialogVisible = ref(false)<el-dialog v-model="dialogVisible" title="添加弹层" width="30%"><div>我是内容部分</div><template #footer><span class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary"> 确认 </el-button></span></template>
</el-dialog>
- 点击事件
<template #extra><el-button type="primary" @click="onAddChannel">添加分类</el-button></template>const onAddChannel = () => {dialogVisible.value = true
}
封装弹层组件 ChannelEdit
添加 和 编辑,可以共用一个弹层,所以可以将弹层封装成一个组件
组件对外暴露一个方法 open, 基于 open 的参数,初始化表单数据,并判断区分是添加 还是 编辑
- open({ }) => 添加操作,添加表单初始化无数据
- open({ id: xx, … }) => 编辑操作,编辑表单初始化需回显
具体实现:
- 封装组件
article/components/ChannelEdit.vue
<script setup>
import { ref } from 'vue'
const dialogVisible = ref(false)const open = async (row) => {dialogVisible.value = trueconsole.log(row)
}defineExpose({open
})
</script><template><el-dialog v-model="dialogVisible" title="添加弹层" width="30%"><div>我是内容部分</div><template #footer><span class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary"> 确认 </el-button></span></template></el-dialog>
</template>
- 通过 ref 绑定
const dialog = ref()<!-- 弹窗 -->
<channel-edit ref="dialog"></channel-edit>
- 点击调用方法显示弹窗
const onAddChannel = () => {dialog.value.open({})
}
const onEditChannel = (row) => {dialog.value.open(row)
}
ChannelEdit.vue(封装的组件)
<script setup>
import {ref} from 'vue'const dialogVisible = ref(false) //弹层状态// 组件对外暴露一个方法,open ,基于open 传来的参数,区分添加还是编辑
// open ({}) => 表单无需渲染,说明是添加分
// open ({id, name}) => 表单需要渲染,说明是编辑分类
// open调用后,可以打开弹窗
const open = (row) =>{console.log(row)dialogVisible.value = true}
// 向外暴露一个方法,close,关闭弹窗
defineExpose({open
})
</script><template>//弹层<el-dialogv-model="dialogVisible"title="添加弹层"width="500":before-close="handleClose"><div>渲染表单</div><span>我是内容部分 </span><template #footer><div class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="dialogVisible = false">确认</el-button></div></template></el-dialog>
</template>
ArticleChannel.vue
<script setup>
import { artGetChannelsService } from '@/api/article'
import { Delete,Edit } from '@element-plus/icons-vue'import {ref} from 'vue'
import ChannelEdit from './components/ChannelEdit.vue'
const channelList = ref([]) // 文章分类列表
const loading = ref(false) //加载状态const dialog = ref()
// 获取文章分类列表
const getChannelList = async () => {// 发请求之前先将loading设置为trueloading.value = true// 调用接口const res = await artGetChannelsService()channelList.value = res.data.data// channelList.value = []// 发完请求,关闭loadingloading.value = false// console.log('文章分类列表',channelList.value);}// 调用获取文章分类列表
getChannelList()// 编辑文章分类
const onEditChannel =(row) =>{
// console.log(row,$index)
dialog.value.open({row})
} // 删除文章分类
const onDelChannel =(row,$index)=>{console.log(row,$index)}
const onAddChannel = () => {dialog.value.open({})
}</script><template><div><!-- 按需引入 --><page-container title="文章分类"> <!-- 右侧按钮 - 添加文章 - 具名插槽 --><template #extra><el-button @click="onAddChannel">添加分类</el-button></template><!-- 主体部分--表格 --><el-table :data="channelList" style="width: 100%" v-loading="loading"><el-table-column label="序号" type="index" width="100" ></el-table-column><el-table-column label="分类名称" prop="cate_name" ></el-table-column><el-table-column label="分类别名" prop="cate_alias" ></el-table-column><el-table-column label="操作" width="100"><template #default="{row,$index}"><el-button @click="onEditChannel(row,$index)" plain :icon="Edit" circle type="primary" ></el-button><el-button @click="onDelChannel(row,$index)" plain :icon="Delete" circle type="danger" ></el-button></template></el-table-column><!-- 没有数据 --><template #empty><el-empty description="暂无数据"></el-empty></template></el-table><!-- 添加分类弹窗 --><channel-edit ref="dialog"> </channel-edit></page-container></div>
</template><style lang="scss" scoped>
</style>
预览视图

准备弹层表单
- 准备数据 和 校验规则
const formModel = ref({cate_name: '',cate_alias: ''
})
const rules = {cate_name: [{ required: true, message: '请输入分类名称', trigger: 'blur' },{pattern: /^\S{1,10}$/,message: '分类名必须是1-10位的非空字符',trigger: 'blur'}],cate_alias: [{ required: true, message: '请输入分类别名', trigger: 'blur' },{pattern: /^[a-zA-Z0-9]{1,15}$/,message: '分类别名必须是1-15位的字母数字',trigger: 'blur'}]
}
- 准备表单
<el-form:model="formModel":rules="rules"label-width="100px"style="padding-right: 30px"
><el-form-item label="分类名称" prop="cate_name"><el-inputv-model="formModel.cate_name"minlength="1"maxlength="10"></el-input></el-form-item><el-form-item label="分类别名" prop="cate_alias"><el-inputv-model="formModel.cate_alias"minlength="1"maxlength="15"></el-input></el-form-item>
</el-form>
- 编辑需要回显,表单数据需要初始化
const open = async (row) => {dialogVisible.value = trueformModel.value = { ...row }//不回显的话,需要修改为// formModel.value = {...row.row} 即可
}
- 基于传过来的表单数据,进行标题控制,有 id 的是编辑
:title="formModel.id ? '编辑分类' : '添加分类'"
确认提交
api/article.js封装请求 API
// 添加文章分类
export const artAddChannelService = (data) => request.post('/my/cate/add', data)
// 编辑文章分类
export const artEditChannelService = (data) =>request.put('/my/cate/info', data)
- 页面中校验,判断,提交请求
<el-form ref="formRef">
const formRef = ref()
const onSubmit = async () => {await formRef.value.validate()formModel.value.id? await artEditChannelService(formModel.value): await artAddChannelService(formModel.value)ElMessage({type: 'success',message: formModel.value.id ? '编辑成功' : '添加成功'})dialogVisible.value = false
}
- 通知父组件进行回显
const emit = defineEmits(['success'])const onSubmit = async () => {...emit('success')
}
- 父组件监听 success 事件,进行调用回显
<channel-edit ref="dialog" @success="onSuccess"></channel-edit>const onSuccess = () => {getChannelList()
}
源码
ChannelEdit.vue
<script setup>
import {ref} from 'vue'const dialogVisible = ref(false) //弹层状态// 组件对外暴露一个方法,open ,基于open 传来的参数,区分添加还是编辑
// open ({}) => 表单无需渲染,说明是添加分
// open ({id, name}) => 表单需要渲染,说明是编辑分类
// open调用后,可以打开弹窗
const open = async (row) =>{// console.log(row)dialogVisible.value = trueformModel.value = {...row.row} //添加 =》 重置了表单内容,编辑-> 存储了需要回显的数据
console.log('formModel:',formModel.value)
console.log(formModel.value.row.cate_name)}// 向外暴露一个方法,close,关闭弹窗
defineExpose({open
})const formModel = ref({cate_name:'',cate_alias:'' //别名
})// 表单校验规则
const rules ={cate_name:[{required:true,message:'请输入分类名称',trigger:'blur'},{pattern:/^\S{1,10}$/,message:'分类名称长度在1-10个字符之间',trigger:'blur'}],cate_alias:[{required:true,message:'请输入分类别名',trigger:'blur'},{pattern:/^[a-zA-Z0-9]{1,15}$/,message:'分类名称长度在1-15个字母或数字之间',trigger:'blur'}]}// 表单提交
import { artEditChannelService,artAddChannelService } from '@/api/article'
// import { ElMessage } from 'element-plus';
const formRef = ref()
const emit = defineEmits(['success'])
const onSubmit = async () => {await formRef.value.validate()const isEdit = formModel.value.idif(isEdit){// 编辑await artEditChannelService(formModel.value)ElMessage.success('编辑成功') }else {// 添加await artAddChannelService(formModel.value)ElMessage.success('添加成功')}// 无论编辑成功还是添加成功都需要关闭弹窗dialogVisible.value = falseemit('success',isEdit) // 触发父组件的success事件}
</script><template><el-dialog v-model="dialogVisible":title="formModel.id ? '编辑分类' : '添加分类'"width="500":before-close="handleClose"><!-- 渲染表单 --><el-form ref="formRef" :model="formModel" :rules="rules" label-width="100px" style="padding-right:30px ;"><el-form-item label="分类名称" prop="cate_name" ><el-input v-model="formModel.cate_name" placeholder="请输入分类名称"></el-input></el-form-item><el-form-item label="分类别名" prop="cate_alias" ><el-input v-model="formModel.cate_alias" placeholder="请输入分类别名"></el-input></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="onSubmit"> 确认 </el-button></div></template></el-dialog>
</template>
ArticleChannel.vue
<script setup>
import { artGetChannelsService } from '@/api/article'
import { Delete,Edit } from '@element-plus/icons-vue'import {ref} from 'vue'
import ChannelEdit from './components/ChannelEdit.vue'
const channelList = ref([]) // 文章分类列表
const loading = ref(false) //加载状态const dialog = ref()
// 获取文章分类列表
const getChannelList = async () => {// 发请求之前先将loading设置为trueloading.value = true// 调用接口const res = await artGetChannelsService()channelList.value = res.data.data// channelList.value = []// 发完请求,关闭loadingloading.value = false// console.log('文章分类列表',channelList.value);}// 调用获取文章分类列表
getChannelList()// 编辑文章分类
const onEditChannel =(row) =>{
// console.log(row,$index)
dialog.value.open({row})
} // 删除文章分类
const onDelChannel =(row,$index)=>{console.log(row,$index)}
const onAddChannel = () => {dialog.value.open({})
}const onSuccess =()=>{// 刷新文章分类列表getChannelList()
}</script><template><div><!-- 按需引入 --><page-container title="文章分类"> <!-- 右侧按钮 - 添加文章 - 具名插槽 --><template #extra><el-button @click="onAddChannel">添加分类</el-button></template><!-- 主体部分--表格 --><el-table :data="channelList" style="width: 100%" v-loading="loading"><el-table-column label="序号" type="index" width="100" ></el-table-column><el-table-column label="分类名称" prop="cate_name" ></el-table-column><el-table-column label="分类别名" prop="cate_alias" ></el-table-column><el-table-column label="操作" width="100"><template #default="{row,$index}"><el-button @click="onEditChannel(row,$index)" plain :icon="Edit" circle type="primary" ></el-button><el-button @click="onDelChannel(row,$index)" plain :icon="Delete" circle type="danger" ></el-button></template></el-table-column><!-- 没有数据 --><template #empty><el-empty description="暂无数据"></el-empty></template></el-table><!-- 添加分类弹窗 --><channel-edit ref="dialog" @success="onSuccess"> </channel-edit></page-container></div>
</template><style lang="scss" scoped>
</style>
预览视图

文章分类删除
api/article.js封装接口 api
// 删除文章分类
export const artDelChannelService = (id) =>request.delete('/my/cate/del', {params: { id }})
- 页面中添加确认框,调用接口进行提示(
ArticleChannel.vue)
const onDelChannel = async (row) => {await ElMessageBox.confirm('你确认删除该分类信息吗?', '温馨提示', {type: 'warning',confirmButtonText: '确认',cancelButtonText: '取消'})await artDelChannelService(row.id)ElMessage({ type: 'success', message: '删除成功' })getChannelList()
}
预览视图

文章分类模块完结,撒花儿~~***
相关文章:
后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0926)
十四、文章分类添加编辑 [element-plus 弹层] Git仓库:https://gitee.com/msyycn/vue3-hei-ma.git 点击显示弹层 准备弹层 const dialogVisible ref(false)<el-dialog v-model"dialogVisible" title"添加弹层" width"30%">…...
验收测试:从需求到交付的全程把控!
在软件开发过程中,验收测试是一个至关重要的环节。它不仅是对软件质量的把关,也是对整个项目周期的全程把控。从需求分析到最终的软件交付,验收测试都需要严格进行,以确保软件能够符合预期的质量和性能要求。 一、需求分析阶段 在…...
第十七节 鼠标的操作与相应
知识点 -event代表鼠标事件类型 -EVENT_LBUTTONDOWN鼠标左键按下 -EVENT_LBUTTONUP鼠标左键抬起 -EVENT_LBUTTONMOVE鼠标及移动 Point sp(-1, -1); Point ep(-1, -1); Mat temp; static void on_draw(int event, int x, int y, int flags, void* userdata) { Mat imag…...
深圳·2025胶粘剂展会 BOND第六届胶展
BOND第六届胶展、2025大湾区国际胶粘剂及密封剂展览会 时间:2025年6月25-27日 地址:深圳国际会展中心(新馆) UV胶、快干胶、结构粘结胶、导热胶、低温黑胶、硅胶、SMT贴片红胶、底部填充胶、低温热固胶、COB黑胶、围堰填充胶、U…...
什么是网络安全自动化以及优势与挑战
目录 网络安全自动化的工作原理 网络安全自动化的好处 增强的安全功能 改善表现和姿势 降低安全成本 简化的安全合规性和审计 更好的端点管理 网络安全自动化的挑战 耗时且容易出错的安全流程 可见性降低,风险和成本增加 合规管理 有用的网络安全自动化…...
java中的ArrayList和LinkedList的底层剖析
引入: 数据结构的分类,数据结构可以分成:线性表,树形结构,图形结构。 线性结构(线性表)包括:数组、链表、栈队列 树形结构:二叉树、AVL树、红黑树、B树、堆、Trie、哈夫曼树、并查集 图形结构:邻接矩阵、邻接表 线性表是具有存…...
占领矩阵-第15届蓝桥省赛Scratch中级组真题第5题
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第190讲。 如果想持续关注Scratch蓝桥真题解读,可以点击《Scratch蓝桥杯历年真题》并订阅合集,…...
[论文笔记] Chain-of-Thought Reasoning without Prompting
分析: 在CoT解码路径中,我们可以看到模型在第三个位置(𝑖? = 3)开始展示推理过程,并且给出了正确的答案“8”。模型首先识别出说话者有3个苹果,然后识别出爸爸比说话者多2个,即5个苹果,最后将这两个数量相加得到总数8个苹果。 这个例子表明,通过探索替代的解码路径…...
C++八股进阶
之前那个只是总结了一下常考点,这个是纯手打记笔记加深理解 这里写目录标题 C的四种智能指针为什么要使用智能指针?四种智能指针: C中的内存分配情况C中的指针参数传递和引用参数传递C 中 const 和 static 关键字(定义࿰…...
渗透测试--文件上传常用绕过方式
文件上传常用绕过方式 1.前端代码,限制只允许上传图片。修改png为php即可绕过前端校验。 2.后端校验Content-Type 校验文件格式 前端修改,抓取上传数据包,并且修改 Content-Type 3.服务端检测(目录路径检测) 对目…...
音视频生态下Unity3D和虚幻引擎(Unreal Engine)的区别
技术背景 好多开发者跟我们做技术交流的时候,会问我们,为什么有Unity3D的RTMP|RTSP播放模块,还有RTMP推送和轻量级RTSP服务模块,为什么不去支持虚幻引擎?二者区别在哪里?本文就Unity3D和虚幻引擎之间的差异…...
搭建基于H.265编码的RTSP推流云服务器
一、前言 网上能够找到的RTSP流地址,均是基于H.264编码的RTSP流地址,无法测试应用是否可以播放H265实时流为此,搭建本地的把H.264转码成H.265的RTSP服务器,不管是通过VLC搭建本地RTSP服务器,还是通过FFmpeg搭建本地RT…...
C++20 std::format
一、前言 1、传统 C 格式化的问题与挑战 可读性差:使用 C 中的 printf 和 scanf 家族函数进行格式化输出和输入时,它们的语法较为复杂,难以阅读。在较大的代码项目中,可读性差会导致维护困难。类型安全性差:printf 和…...
Python基础知识 (九)os模块、异常、异常的传递性
目录 OS模块 目录的具体操作 什么是异常 异常常见处理方式 异常分类: 捕获一个指定异常 捕获多个异常 捕获所有异常 异常具有传递性 OS模块 在Python中,os模块的常用函数分为两类: (a)通过os.path调用的函数…...
鸿蒙手势交互(三:组合手势)
三、组合手势 由多种单一手势组合而成,通过在GestureGroup中使用不同的GestureMode来声明该组合手势的类型,支持顺序识别、并行识别和互斥识别三种类型。 GestureGroup(mode:GestureMode, gesture:GestureType[]) //- mode:为GestureMode枚…...
【计算机方向】中科院二区TOP神刊!国人发文友好,刊文量高,录用容易!
期刊解析 🚩本 期 期 刊 看 点 🚩 中科院二区TOP期刊! 审稿友好,IF4.8,自引率6.2% 最新年度发文530。 今天小编带来计算机领域SCI快刊的解读! 如有相关领域作者有意投稿,可作为重点关注&am…...
Stable Diffusion 保姆级教程
1. 引言 近年来,Stable Diffusion 成为了图像生成领域的热门技术,它是一种基于扩散模型的生成模型,可以通过输入简单的文本描述生成高质量的图像。相比传统的生成对抗网络(GAN),Stable Diffusion 更具稳定…...
踩坑记录:adb修改settings数据库ContentObserver无回调
在Android 14版本开发过程中遇到一个,通过adb修改settings数据库,发现生效但是监听的ContentObserver无回调 以背光亮度值调节为例 adb shell settings put system screen_brightness 18 调节亮度值到指定值,修改完后查看 adb shell set…...
JAVA毕业设计183—基于Java+Springboot+vue的旅游小程序系统(源代码+数据库)
毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue的旅游小程序系统(源代码数据库)183 一、系统介绍 本项目前后端不分离,分为用户、管理员两种角色 1、用户: 注册、登录、公告信息(…...
[大语言模型] 情感认知在大型语言模型中的近期进展-2024-09-26
[大语言模型] 情感认知在大型语言模型中的近期进展-2024-09-26 论文信息 Title: Recent Advancement of Emotion Cognition in Large Language Models Authors: Yuyan Chen, Yanghua Xiao https://arxiv.org/abs/2409.13354 情感认知在大型语言模型中的近期进展 《Recent A…...
终极指南:10分钟掌握SPT-AKI存档编辑器完整使用教程
终极指南:10分钟掌握SPT-AKI存档编辑器完整使用教程 【免费下载链接】SPT-AKI-Profile-Editor Программа для редактирования профиля игрока на сервере SPT-AKI 项目地址: https://gitcode.com/gh_mirrors/sp/…...
别再只盯着wx.login了!SpringBoot后端实战:用getPhoneNumber接口搞定小程序用户手机号绑定
微信小程序用户手机号绑定:SpringBoot后端深度实践指南 在当今移动互联网生态中,微信小程序已成为连接用户与服务的重要桥梁。对于需要强实名认证或直接触达用户的业务场景(如电商交易、金融服务、政务办理等),仅依赖w…...
从myplaces.shp到专题地图:手把手教你用QGIS C++ API实现点要素分级渲染
从myplaces.shp到专题地图:QGIS C API实现点要素分级渲染实战指南 当我们需要在桌面GIS应用中直观展示气象站降雨量、城市人口密度或商业网点销售额等连续型空间数据时,分级色彩渲染是最有效的可视化手段之一。本文将深入探讨如何利用QGIS强大的C API&am…...
告别黑盒:5分钟为你的自定义CNN模型集成Grad-CAM可视化(附常见错误排查)
告别黑盒:5分钟为你的自定义CNN模型集成Grad-CAM可视化(附常见错误排查) 在深度学习项目中,我们常常陷入一个尴尬境地:模型准确率很高,但完全不知道它究竟"看"了图像的哪些部分做出决策。这种黑盒…...
C++定时器避坑指南:线程安全、资源泄漏与时间轮参数怎么调?一次讲清楚
C定时器避坑指南:线程安全、资源泄漏与时间轮参数调优实战 在分布式系统和高并发场景中,定时器如同系统的心跳机制,其稳定性直接决定服务可靠性。去年某电商平台大促期间,由于定时任务堆积导致的雪崩效应,造成近千万损…...
从GitHub克隆到点亮LED:手把手教你用Ubuntu编译调试别人的STM32工程
从GitHub克隆到点亮LED:手把手教你用Ubuntu编译调试别人的STM32工程 在开源硬件社区,GitHub上每天都有大量优秀的STM32项目被分享——从智能家居控制器到四轴飞行器飞控系统。但当开发者满怀期待地git clone后,却常常在第一步"编译通过&…...
Ruby专属LLM应用框架ruby_llm:从基础集成到生产部署实战
1. 项目概述:一个为Ruby语言量身打造的LLM应用框架如果你是一名Ruby开发者,最近被各种大语言模型(LLM)的应用搞得心痒痒,但看着满世界的Python库和框架感到无从下手,那么crmne/ruby_llm这个项目可能就是你在…...
Ruby LLM框架:为Ruby开发者打造的大语言模型应用开发工具包
1. 项目概述:一个为Ruby语言量身打造的LLM应用框架如果你是一名Ruby开发者,最近被各种大语言模型(LLM)的应用搞得心痒痒,但看着满世界的Python库和框架感到无从下手,那么crmne/ruby_llm这个项目可能就是你在…...
WipperSnapper+Adafruit IO:无代码物联网开发实战,从传感器到云端自动化
1. 项目概述与核心价值如果你和我一样,在物联网(IoT)项目初期,常常被复杂的嵌入式编程、网络协议和云平台对接搞得焦头烂额,那么今天分享的这个实战项目,或许能让你眼前一亮。我们这次不谈复杂的代码&#…...
从零构建现代化工作流引擎:架构、实战与生产级部署指南
1. 项目概述:一个为专业开发者打造的现代化工作流引擎最近在GitHub上看到一个挺有意思的项目,叫rohitg00/pro-workflow。光看名字,你可能觉得这又是一个“工作流”工具,市面上这类工具已经多如牛毛了。但当我深入去研究它的源码、…...
