springboot + Vue前后端项目(第十六记)

项目实战第十六记

  • 写在前面
  • 1 第一个bug
    • 1.1 完整的Role.vue
  • 2 第二个bug
    • 2.1 修改路由router下面的index.js
  • 总结
  • 写在最后

写在前面

  • 发现bug,修复bug

1 第一个bug

分配菜单时未加入父id,导致分配菜单失效

<!-- :check-strictly="true"   默认是false,父子关联;true 是不关联需手动勾选父选择框
-->
<el-tree:props="props":data="menuData"show-checkboxnode-key="id"ref="tree":check-strictly="true":default-expanded-keys="expends":default-checked-keys="checks"><span class="custom-tree-node" slot-scope="{ node, data }"><span><i :class="data.icon"></i> {{ data.name }}</span></span></el-tree>

1.1 完整的Role.vue

<template><div><!-- 设计的查询 --><div style="margin: 10px 0"><el-inputstyle="width: 200px"placeholder="请输入名称"suffix-icon="el-icon-search"v-model="name"/><el-button type="primary" icon="el-icon-search" class="ml-5" @click="getList">搜索</el-button><el-button type="warning" icon="el-icon-reset" @click="resetQuery">重置</el-button></div><div style="margin: 10px 0"><el-button type="primary" @click="handleAdd">新增 <i class="el-icon-circle-plus-outline"></i></el-button><el-button type="warning" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate">修改</el-button><el-button type="danger" :disabled="multiple" @click="handleDelete">删除 <i class="el-icon-remove-outline"></i></el-button></div><el-table :data="tableData" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55" /><el-table-column prop="id" label="角色ID" width="80"></el-table-column><el-table-column prop="roleKey" label="唯一标识"></el-table-column><el-table-column prop="name" label="角色名称"></el-table-column><el-table-column prop="description" label="角色描述"></el-table-column><el-table-column label="操作"><template v-slot="scope"><el-buttontype="info"icon="el-icon-menu"@click="openMenuAllocDialog(scope.row.id)">分配菜单</el-button><el-button type="success" @click="handleUpdate(scope.row)">编辑 <i class="el-icon-edit"></i></el-button><el-button type="danger" @click="handleDelete(scope.row)">删除 <i class="el-icon-remove-outline"></i></el-button></template></el-table-column></el-table><div style="padding: 10px 0"><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="pageNum":page-sizes="[5, 10, 15]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></div><!-- 角色添加对话框 --><el-dialog title="角色信息" :visible.sync="dialogFormVisible" width="30%"><el-form :model="form"><el-form-item label="唯一标识" :label-width="formLabelWidth"><el-input v-model="form.roleKey" autocomplete="off"></el-input></el-form-item><el-form-item label="角色名称" :label-width="formLabelWidth"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item><el-form-item label="描述" :label-width="formLabelWidth"><el-input v-model="form.description" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="save">确 定</el-button></div></el-dialog><!-- 分配菜单 --><el-dialog title="菜单分配" :visible.sync="menuDialogVis" width="30%"><el-tree:props="props":data="menuData"show-checkboxnode-key="id"ref="tree":check-strictly="true":default-expanded-keys="expends":default-checked-keys="checks"><span class="custom-tree-node" slot-scope="{ node, data }"><span><i :class="data.icon"></i> {{ data.name }}</span></span></el-tree><div slot="footer" class="dialog-footer"><el-button @click="menuDialogVis = false">取 消</el-button><el-button type="primary" @click="saveRoleMenu">确 定</el-button></div></el-dialog></div>
</template>
<script>
export default {name: "Role",data() {return {name: "",tableData: [],total: 0,pageSize: 5,pageNum: 1,dialogFormVisible: false,menuDialogVis: false,formLabelWidth: "80px",ids: [],// 非单个禁用single: true,// 非多个禁用multiple: true,form: {id: "",name: "",description: "",},menuData: [],props: {label: 'name',},expends: [],checks: [],roleId: undefined,};},//页面一创建成功created() {//请求分页查询数据this.getList();},methods: {getList() {this.request.get("/role/page", {params: {pageNum: this.pageNum,pageSize: this.pageSize,name: this.name,},}).then((res) => {if(res.code === "200"){this.tableData = res.data.records;this.total = res.data.total;}else{this.$message.error(res.msg);}});},//分配菜单openMenuAllocDialog(id){this.menuDialogVis = true;// 角色id赋值this.roleId = id;//请求菜单数据this.request.get("/menu",{params: {name: ""}}).then(res => {this.menuData = res.data;//展开菜单数据this.expends = this.menuData.map(v => v.id);})// 展开已拥有的菜单this.request.get("/role/roleMenu/"+id).then(res => {this.checks = res.data;})},//保存角色下的菜单saveRoleMenu(){console.log('======',this.$refs.tree.getCheckedKeys());this.request.post("/role/roleMenu/"+ this.roleId, this.$refs.tree.getCheckedKeys()).then(res => {if(res.code === "200"){this.$message.success("保存成功");this.menuDialogVis = false;}else {this.$message.error("保存失败");}})},// 重置按钮resetQuery(){this.username = "";this.pageNum = 1;this.pageSize = 5;this.getList();},handleSizeChange(val) {this.pageSize = val;},handleCurrentChange(val) {this.pageNum = val;this.getList();},// 多选框选中数据handleSelectionChange(selection) {this.ids = selection.map(item => item.id);this.single = selection.length != 1;this.multiple = !selection.length;},// 新增handleAdd(){this.dialogFormVisible = true;this.form = {};},save(){this.request.post("/role",this.form).then(res => {if(res.code === "200" || res.code === 200){this.$message.success("操作成功")}else {this.$message.error("操作失败")}this.dialogFormVisible = false;this.getList();})},// 修改handleUpdate(row){// 表单置空this.reset();// 重新查询数据const roleId = row.id || this.ids;this.request.get('/role/'+roleId).then(response => {this.form = response.data;this.dialogFormVisible = true;});},reset(){this.form.roleKey = undefined;this.form.name = undefined;this.form.description = undefined;},// 删除handleDelete(row){let _this = this;const roleIds = row.id || this.ids;this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', '删除角色', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {_this.request.delete("/role/"+roleIds).then(res=>{if(res.code === "200" || res.code === 200){_this.$message.success("删除成功")}else {_this.$message.error("删除失败")}this.getList();})}).catch(() => {});}},
};
</script>

2 第二个bug

启动成功前端访问地址,弹出的是404页面不是登录页面
在这里插入图片描述

2.1 修改路由router下面的index.js

修改的地方

// 第一处
{path: '/404',name: '404',component: () => import('../views/404.vue')}// 第二处
// 路由守卫
router.beforeEach((to, from, next) => {// localStorage.setItem('currentPathName',to.name);   // 设置当前的路由名称,为了在Header组件中去使用// store.commit('setPath')    // 触发store的数据更新// 未找到路由情况if(!to.matched.length){const storeMenus = localStorage.getItem("menus");if(storeMenus){   // 有菜单没有找到路由,跳转至 404页面next("/404")}else {    // // 没有菜单,直接跳转至登录页next("/login")}}next()   // 放行路由
})

完整的代码

import Vue from 'vue'
import VueRouter from 'vue-router'
import Manage from '../views/Manage.vue'
import store from "@/store";Vue.use(VueRouter)
//定义一个路由对象数组
const routes = [{path: '/login',name: '登录',component: () => import('../views/Login.vue')},{path: '/register',name: '注册',component: () => import('../views/Register.vue')},{path: '/404',name: '404',component: () => import('../views/404.vue')}]//使用路由对象数组创建路由实例,供main.js引用
const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})// 注意:刷新页面会导致页面路由重置
export const setRoutes = () => {const storeMenus = localStorage.getItem("menus");if (storeMenus) {// 获取当前的路由对象名称数组const currentRouteNames = router.getRoutes().map(v => v.name)if (!currentRouteNames.includes('Manage')) {// 拼装动态路由const manageRoute = { path: '/', name: 'Manage', component: () => import('../views/Manage.vue'), redirect: "/home", children: [{ path: 'person', name: '个人信息', component: () => import('../views/Person.vue')},// { path: 'password', name: '修改密码', component: () => import('../views/Password.vue')}] }const menus = JSON.parse(storeMenus)menus.forEach(item => {if (item.path) {  // 当且仅当path不为空的时候才去设置路由let itemMenu = { path: item.path.replace("/", ""), name: item.name, component: () => import('../views/' + item.pagePath + '.vue'),meta: { title: item.name }}manageRoute.children.push(itemMenu)} else if(item.children.length) {item.children.forEach(item => {if (item.path) {let itemMenu = { path: item.path.replace("/", ""), name: item.name, component: () => import('../views/' + item.pagePath + '.vue'),meta: { title: item.name }}manageRoute.children.push(itemMenu)}})}})// 动态添加到现在的路由对象中去router.addRoute(manageRoute)}}
}// 重置我就再set一次路由
setRoutes()// 路由守卫
router.beforeEach((to, from, next) => {// localStorage.setItem('currentPathName',to.name);   // 设置当前的路由名称,为了在Header组件中去使用// store.commit('setPath')    // 触发store的数据更新// 未找到路由情况if(!to.matched.length){const storeMenus = localStorage.getItem("menus");if(storeMenus){   // 有菜单没有找到路由,跳转至 404页面next("/404")}else {    // // 没有菜单,直接跳转至登录页next("/login")}}// 其他情况next()   // 放行路由
})export default router

总结

  • 动态菜单完结,基本项目也快接近尾声。

写在最后

如果此文对您有所帮助,请帅戈靓女们务必不要吝啬你们的Zan,感谢!!不懂的可以在评论区评论,有空会及时回复。
文章会一直更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/353299.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程控制3——进程程序替换

一&#xff0c;前言 创建子进程的目的之一就是为了代劳父进程执行父进程的部分代码&#xff0c;也就是说本质上来说父子进程都是执行的同一个代码段的数据&#xff0c;在子进程修改数据的时候进行写时拷贝修改数据段的部分数据。 但是还有一个目的——将子进程在运行时指向一个…

SpringBoot的事务注解

SpringBoot的事务注解 在Spring Boot应用中&#xff0c;事务管理是一个关键的部分&#xff0c;尤其是当涉及到数据库操作时。Spring Boot提供了强大的事务管理支持&#xff0c;使得开发人员可以通过简单的注解来控制事务的边界和行为。本文将介绍如何在Spring Boot中使用事务注…

vue部署宝塔nginx配置(获取用户ip地址、反代理访问api接口、websocket转发)

以下配置为我自己的需求&#xff0c;因人而异&#xff0c;如果只是单纯的前端非交互页面&#xff0c;可以不用修改配置。 代码及注释&#xff0c;如下&#xff1a; #解决vue-router设置mode为history&#xff0c;去掉路由地址上的/#/后nginx显示404的问题location / {proxy_htt…

VS2019+QT5.15调用动态库dll带有命名空间

VS2019QT5.15调用动态库dll带有命名空间 vs创建动态库 参考&#xff1a; QT调用vs2019生成的c动态库-CSDN博客 demo的dll头文件&#xff1a; // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号…

如何快速搭建满足用户需求的运营体系?Xinstall来支招!

随着互联网的飞速发展&#xff0c;App的推广和运营面临着越来越多的挑战。传统的营销手段逐渐失效&#xff0c;如何在这个多变的互联网环境下&#xff0c;迅速搭建起能满足用户需求的运营体系&#xff0c;成为了众多企业关注的焦点。而Xinstall&#xff0c;作为一款专业的App推…

Spring Cloud Alibaba Nacos作为服务配置中心实践

Nacos官网文档&#xff1a;Nacos 融合 Spring Cloud&#xff0c;成为注册配置中心 【1】服务实例 ① pom依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </de…

充电学习—7、BC1.2 PD协议

BC1.2&#xff08;battery charging&#xff09;充电端口识别机制&#xff1a; SDP、CDP、DCP 1、VBUS detect&#xff1a;vbus检测 PD&#xff08;portable device&#xff0c;便携式设备&#xff09;中有个检测VBUS是否有效的电路&#xff0c;电路有个参考值&#xff0c;高…

软件设计不是CRUD(23):在流式数据处理系统中进行业务抽象落地——详细编码

&#xff08;接上文《软件设计不是CRUD&#xff08;22&#xff09;&#xff1a;在流式数据处理系统中进行业务抽象落地——设计思考》&#xff09; 4、详细设计 项目开发初期&#xff0c;有两种测速雷达和对应的摄像头需要接入&#xff0c;分别是STC500型测速雷达和TTS400型测…

如何打开azw/azw3文件?两个步骤解决

要打开AZW或AZW3格式的电子书&#xff0c;遵循以下步骤&#xff0c;无论你是Windows、Mac用户&#xff0c;还是使用移动设备&#xff0c;都可以轻松阅读这些亚马逊Kindle专用格式的电子书&#xff1a; 第一步&#xff1a;安装NeatReader&#xff1a; 访问NeatReader的官方网站或…

Windows系统部署本地SQL_Server指引

Windows系统部署本地SQL_Server指引 此指引文档环境为Windows10系统&#xff0c;部署SQL_Server 2019为例&#xff0c;同系列系统软件安装步骤类似。 一、部署前准备&#xff1b; 下载好相关镜像文件&#xff1b;设备系统启动后&#xff0c;将不必要的软件停用&#xff0c;避…

MoonBit 亮相港科大「 INNOTECH 创科嘉年华」,技术创新实力备受瞩目

INNOTECH创科嘉年华 6月16日&#xff0c; MoonBit 作为 IDEA 研究院重点项目成果受邀参与一年一度由香港科技大学&#xff08;广州&#xff09;主办的「INNOTECH 创科嘉年华」&#xff0c;作为港科大&#xff08;广州&#xff09;每年最重要的科创实力展示机会&#xff0c;本次…

阿里云平台创建设备及连接

使用阿里云平台创建项目&#xff0c;利用MQTT.fx软件配置相关的连接&#xff0c;在软件上完成消息的订阅与推送&#xff0c;与手机APP进行同步数据。了解MQTT相关的协议。 1.注册阿里云平台账号&#xff0c;完成实名注册&#xff01; 618创新加速季_新迁入云享5亿算力补贴-阿里…

MySQL常见面试题自测

文章目录 MySQL基础架构一、说说 MySQL 的架构&#xff1f;二、一条 SQL语句在MySQL中的执行过程 MySQL存储引擎一、MySQL 提供了哪些存储引擎&#xff1f;二、MySQL 存储引擎架构了解吗&#xff1f;三、MyISAM 和 InnoDB 的区别&#xff1f; MySQL 事务一、何谓事务&#xff1…

安卓软件自动运行插件的开发源代码介绍!

随着移动互联网的快速发展&#xff0c;安卓操作系统凭借其开放性和灵活性&#xff0c;成为了众多开发者们的首选平台&#xff0c;在安卓应用的开发中&#xff0c;为了实现各种复杂的功能&#xff0c;插件化技术逐渐受到青睐。 其中&#xff0c;自动运行插件作为一种能够实现应…

【Linux】环境设置MySQL表名忽略大小写

目录 说明 一、摘要 二、查看服务器上MySQL情况 方式一&#xff1a;通过Linux方式 方式二&#xff1a;借助可视化工具&#xff08;Navicat&#xff09; 三、MySQL设置忽略表名大小写的参数&#xff08;lower_case_table_names&#xff09; 四、网上解决方案 方法一&…

【Spring Cloud应用框架】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

智慧校园的作用是什么?

在近几年&#xff0c;智慧校园以其独有的姿态&#xff0c;悄然改变着教育的面貌。想象一下&#xff0c;当物联网、大数据、人工智能这些前沿技术与传统校园深度融合&#xff0c;教育空间不再局限于实体教室&#xff0c;知识获取也不再受制于时间与地点&#xff0c;一个更加开放…

TikTok账号养号的流程分享

对于很多刚开始运营TikTok的新手小白来说&#xff0c;都会有一个同样的疑问&#xff0c;那就是&#xff1a;TikTok到底需不需要养号&#xff1f;这里明确告诉大家是需要养号的&#xff0c;今天就把我自己实操过的养号经验和策略总结出来&#xff0c;分享给大家。 一、什么是Ti…

AI智能盒子助力中钢天源设备工厂升级安全防护

中钢集团安徽天源科技股份有限公司成立于2002年3月27日,是中央企业中国中钢股份有限公司控股的上市公司&#xff0c;主导产品为永磁铁氧体器件、钕铁硼器件、四氧化三锰、锶铁氧体预烧料及各类磁选机等。 在中钢天源智能化升级过程中&#xff0c;采用并定制开发一系列厂区安全…

关于阿里云效流水线自动部署项目教程

1、登录阿里云效:阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 2、点击左侧流水线&#xff1a; 3、在流水线界面&#xff0c;新建流水线 4、我的是php代码&#xff0c;因此选择php模版 5、创建之后添加流程线源&#xff0c;如下图 6、选择相应的源头。比…