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.mzph.cn/pingmian/28419.shtml

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

相关文章

图的应用之最小生成树

大纲 生成树介绍 特点 但n个 种类 最小生成树 应用 构造算法 MST性质 Prim算法 依次选择与顶点相邻的不会构成回路的最小边对应的顶点 Kruskal算法 依次选不会构成环的最小边 区别 Prim算法有n个顶点进行选择&#xff0c;每个顶点有n个选择&#xff0c;复杂度为O(n*n) K…

C51学习归纳13 --- AD/DA转换

AD/DA转换实现了计算机和模拟信号的连接&#xff0c;扩展了计算机的应用场景&#xff0c;为模拟信号数字化提供了底层支持。 AD转换通常是多个输入通道&#xff0c;使用多路选择器连接到AD开关&#xff0c;实现AD多路复用的目的&#xff0c;提高利用率。 AD/DA转换可以使用串口…

我的创作纪念日(1825天)

Ⅰ、机缘 1. 记得是大一、大二的时候就听学校的大牛说&#xff0c;可以通过写 CSDN 博客&#xff0c;来提升自己的代码和逻辑能力&#xff0c;虽然即将到了写作的第六个年头&#xff0c;但感觉这句话依旧受用; 2、今年一整年的创作都没有停止&#xff0c;本年度几乎是每周都来…

UniApp或微信小程序中scroll-view组件使用show-scrollbar在真机Android或IOS中隐藏不了滚动条的解决办法

show-scrollbar 属性 不论是使用 变量 还是直接使用 布尔值或者直接使用 css 都是在 ios、Android 上是都没有效果。。 真机中还是出现滚动条 解决办法 添加下面CSS ::-webkit-scrollbar {display: none;width: 0 !important;height: 0 !important;-webkit-appearance: no…

盛世古董乱世金-数据库稳定到底好不好?

是不是觉得这个还用问&#xff1f; 是的要问。因为这个还是一个有争议的问题。但是争议双方都没有错。这就像辩论&#xff0c;有正反双方。大家都说的有道理&#xff0c;但是很难说谁对谁错。 正方观点&#xff1a;数据库稳定好 其实这个是用户的观点&#xff0c;应用开发人…

17个关键方法指南,保护您的web站点安全!

了解如何让您的web应用程序或网站安全&#xff0c;对于网站所有者来说至关重要。以下是一些关键步骤&#xff0c;可以帮助您保护网站免受攻击和数据泄露。 1.使用公钥加密技术 当数据以明文形式传输时&#xff0c;它容易受到中间人 &#xff08;MitM&#xff09; 攻击。这意味…

北航第六次数据结构与程序设计作业(查找与排序)选填题

一、 顺序查找的平均查找长度ASL&#xff08;1 2 …… n&#xff09;/ n (n 1&#xff09;/ 2 二、 这半查找法的平均查找次数和判定树的深度有关系。若查找一个不存在的元素&#xff0c;说明进行了深度次比较。 注意&#xff0c;判定树不是满二叉树&#xff0c;因此深…

安卓网络通信(多线程、HTTP访问、图片加载、即时通信)

本章介绍App开发常用的以下网络通信技术&#xff0c;主要包括&#xff1a;如何以官方推荐的方式使用多线程技术&#xff0c;如何通过okhttp实现常见的HTTP接口访问操作&#xff0c;如何使用Dlide框架加载网络图片&#xff0c;如何分别运用SocketIO和WebSocket实现及时通信功能等…

HTTP协议 快速入门

http概述 无状态性&#xff1a;HTTP是一个无状态协议&#xff0c;这意味着服务器不会在请求之间保存任何会话信息。每个请求都是独立的&#xff0c;服务器不会记住之前的请求。 请求-响应模型&#xff1a;HTTP通信是基于客户端发送请求和服务器返回响应的模型。客户端&#xf…

Spark常见的可以优化的点

Shuffle 复用 # 1.以下操作会复用的shuffle结果&#xff0c;只会读一遍数据源 val rdd1 sc.textFile("hdfs://zjyprc-hadoop/tmp/hive-site.xml").flatMap(_.split(" ")).map(x > (x,1)).reduceByKey(_ _).filter(_._2 > 1) rdd1.count() rdd1.fil…

华为od-C卷200分题目2 - 找城市

华为od-C卷200分题目2 - 找城市 题目描述 一个城市规划问题&#xff0c;一个地图有很多城市&#xff0c;两个城市之间只有一种路径&#xff0c;切断通往一 个城市i的所有路径之后&#xff0c;其他的城市形成了独立的城市群&#xff0c;这些城市群里最大的城 市数量&#xff0…

会声会影色彩校正在哪里 会声会影色彩素材栏在哪 会声会影中文免费版下载

会声会影是一款功能强大的视频编辑软件&#xff0c;它可以帮助用户轻松地编辑和制作视频。在进行视频编辑时&#xff0c;色彩校正是一个重要的步骤&#xff0c;它可以调整视频的色调、亮度和对比度等参数&#xff0c;使视频更加生动和鲜明。在会声会影中&#xff0c;色彩校正功…

【Python/Pytorch - 网络模型】-- TV Loss损失函数

文章目录 文章目录 00 写在前面01 基于Pytorch版本的TV Loss代码02 论文下载 00 写在前面 在医学图像重建过程中&#xff0c;经常在代价方程中加入TV 正则项&#xff0c;该正则项作为去噪项&#xff0c;对于重建可以起到很大帮助作用。但是对于一些纹理细节要求较高的任务&am…

MongoDB~分片数据存储Chunk;其迁移原理、影响,以及避免手段

分片数据存储&#xff1a;Chunk存储 Chunk&#xff08;块&#xff09; 是 MongoDB 分片集群的一个核心概念&#xff0c;其本质上就是由一组 Document 组成的逻辑数据单元。每个 Chunk 包含一定范围片键的数据&#xff0c;互不相交且并集为全部数据。 分片集群不会记录每条数据…

Python 基础:类

目录 一、类的概念二、定义类三、创建对象并进行访问四、修改属性的值方法一&#xff1a;句点表示法直接访问并修改方法二&#xff1a;通过方法进行修改 五、继承继承父类属性和方法重写父类方法 六、将实例用作属性七、导入类导入单个类从一个模块中导入多个类导入整个模块导入…

C语言的基本输入输出函数+构造类型数据——数组

C语言的基本输入输出函数 1. 字符输入输出函数 getchar()、putchar() getchar()&#xff1a;从标准输入&#xff08;通常是键盘&#xff09;读取一个字符&#xff0c;并返回其ASCII值。putchar()&#xff1a;将指定的字符&#xff08;由其ASCII值表示&#xff09;写入标准输出…

10_Transformer预热---注意力机制(Attention)

1.1 什么是注意力机制(attention) 注意力机制&#xff08;Attention Mechanism&#xff09;是一种在神经网络中用于增强模型处理特定输入特征的能力的技术。它最早被应用于自然语言处理&#xff08;NLP&#xff09;任务中&#xff0c;特别是在机器翻译中&#xff0c;如Google的…

python14 字典类型

字典类型 键值对方式&#xff0c;可变数据类型&#xff0c;所以有增删改功能 声明方式1 {} 大括号&#xff0c;示例 d {key1 : value1, key2 : value2, key3 : value3 ....} 声明方式2 使用内置函数 dict() 创建1)通过映射函数创建字典zip(list1,list2) 继承了序列的所有操作 …

Linux基础I/O之文件描述符fd 重定向(上)

目录 一、预备知识 二、C语言中的文件接口 三、系统调用中的文件接口 一、预备知识 首先我们要明确的一个观点是 --- 文件 内容 属性。而且我们之前也还将过一个概念&#xff0c;那就是Linux下一切皆文件。 内容是数据&#xff0c;属性也是数据 --- 那么也就是说我…

使用STL算法函数有效提升STL列表的搜索速度(附源码)

STL(Standard Templete Library)活动模板库已被广泛地应用于各种C++程序的开发中,STL中vector、list、map等列表极大地方便了我们日常的开发,不再需要我们去实现链表等数据结构,使用这些列表能基本能解决开发过程中遇到的各种问题。网上关于STL的文章比较多,今天我们就来…