兼職做ps網(wǎng)站百度網(wǎng)盤搜索引擎網(wǎng)站
項(xiàng)目實(shí)戰(zhàn)第十五記
- 寫在前面
- 1.后端接口實(shí)現(xiàn)
- 1.1 用戶表添加角色字段
- 1.2 角色表增加唯一標(biāo)識字段
- 1.3 UserDTO
- 1.4 UserServiceImpl
- 1.5 MenuServiceImpl
- 2. 前端實(shí)現(xiàn)
- 2.1 User.vue
- 2.2 動(dòng)態(tài)菜單設(shè)計(jì)
- 2.2.1 Login.vue
- 2.2.2 Aside.vue
- 2.3 動(dòng)態(tài)路由設(shè)計(jì)
- 2.3.1 菜單表新增字段page_path
- 2.3.2 路由設(shè)計(jì)
- 2.3.3 登錄界面Login.vue設(shè)置路由
- 總結(jié)
- 寫在最后
寫在前面
- 動(dòng)態(tài)菜單設(shè)計(jì)
- 動(dòng)態(tài)路由設(shè)計(jì)
1.后端接口實(shí)現(xiàn)
1.1 用戶表添加角色字段
CREATE TABLE `sys_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`username` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用戶名',`password` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '密碼',`nickname` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '昵稱',`email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '郵箱',`phone` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '電話',`address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址',`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',`avatar_url` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT 'https://himg.bdimg.com/sys/portraitn/item/public.1.23bd3c8c.ANoeKxl_gef9fnrikdXOYA' COMMENT '頭像',`role` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '角色',`deleted` tinyint(4) DEFAULT '0' COMMENT '邏輯刪除0(未刪除),1(刪除)',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC
1.2 角色表增加唯一標(biāo)識字段
CREATE TABLE `sys_role` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`role_key` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '唯一標(biāo)識',`name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名稱',`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述',`deleted` tinyint(1) DEFAULT '0' COMMENT '是否刪除',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC
1.3 UserDTO
@Data
public class UserDTO {private String username;private String password;private String nickname;private String avatarUrl;private String token;private String role;private List<Menu> menus;
}
1.4 UserServiceImpl
package com.ppj.service.impl;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ppj.constants.Constants;
import com.ppj.entity.Menu;
import com.ppj.entity.Role;
import com.ppj.entity.RoleMenu;
import com.ppj.entity.User;
import com.ppj.entity.dto.UserDTO;
import com.ppj.exception.ServiceException;
import com.ppj.mapper.MenuMapper;
import com.ppj.mapper.RoleMapper;
import com.ppj.mapper.RoleMenuMapper;
import com.ppj.mapper.UserMapper;
import com.ppj.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ppj.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.sql.rowset.serial.SerialException;
import java.util.ArrayList;
import java.util.List;/*** <p>* 服務(wù)實(shí)現(xiàn)類* </p>** @author ppj* @since 2024-04-20*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {private static final Log LOG = Log.get();@Autowiredprivate RoleMapper roleMapper;@Autowiredprivate RoleMenuMapper roleMenuMapper;@Autowiredprivate MenuServiceImpl menuService;@Overridepublic UserDTO login(UserDTO userDTO) {if(StrUtil.isBlank(userDTO.getUsername()) || StrUtil.isBlank(userDTO.getPassword())){return null;}User user = getUserInfo(userDTO);if(user != null){String token = TokenUtils.genToken(user.getId().toString(), userDTO.getPassword());userDTO.setToken(token);// 把user相應(yīng)的值傳遞給userDTOBeanUtil.copyProperties(user,userDTO,true);List<Menu> roleMenus = getRoleMenus(user.getRole());userDTO.setMenus(roleMenus);return userDTO;}else{ // 數(shù)據(jù)庫查不到throw new ServiceException(Constants.CODE_600,"用戶名或密碼錯(cuò)誤");}}@Overridepublic Boolean register(UserDTO userDTO) {if(StrUtil.isBlank(userDTO.getUsername()) || StrUtil.isBlank(userDTO.getPassword())){return false;}User user = getUserInfo(userDTO);if(user == null){User newUser = new User();// 值傳遞BeanUtil.copyProperties(userDTO,newUser,true);// 保存至數(shù)據(jù)庫save(newUser);}else{throw new ServiceException(Constants.CODE_600,"用戶已存在");}return true;}public User getUserInfo(UserDTO userDTO){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username",userDTO.getUsername()).eq("password",userDTO.getPassword());User user;try {// 可能查到多條記錄,后臺報(bào)異常,寫個(gè)異常類(主動(dòng)捕獲異常)user = getOne(queryWrapper);}catch (Exception e){ // 可能查出多個(gè)符合條件的記錄LOG.error(e);throw new ServiceException(Constants.CODE_500,"系統(tǒng)錯(cuò)誤");}return user;}/*** 根據(jù)角色名稱獲取菜單列表* @param roleName* @return*/public List<Menu> getRoleMenus(String roleName){Integer roleId = roleMapper.getRoleIdByName(roleName);List<Integer> menuIds = roleMenuMapper.getMenuIdsByRoleId(roleId);// 查詢系統(tǒng)中所有菜單,樹結(jié)構(gòu)List<Menu> menus = menuService.findMenus("");// new一個(gè)最后篩選完成之后的listArrayList<Menu> roleMenus = new ArrayList<>();for (Menu menu : menus) {if(menuIds.contains(menu.getId())){roleMenus.add(menu);}List<Menu> children = menu.getChildren();// 移除children中不在menuIds集合中的元素if (children != null) {children.removeIf(child -> !menuIds.contains(child.getId()));}}return roleMenus;}}
1.5 MenuServiceImpl
將寫在MenuController中的方法提取到service中(更符合現(xiàn)實(shí)中的開發(fā))
如下圖所示:controller不含業(yè)務(wù)代碼
package com.ppj.service.impl;import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ppj.entity.Menu;
import com.ppj.mapper.MenuMapper;
import com.ppj.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.stream.Collectors;/*** <p>* 服務(wù)實(shí)現(xiàn)類* </p>** @author ppj* @since 2024-05-29*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {public List<Menu> findMenus(String name) {QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();if(StrUtil.isNotBlank(name)){queryWrapper.like("name",name);}List<Menu> list = list(queryWrapper);//找出一級菜單List<Menu> parentNodes = list.stream().filter(menu -> menu.getPid() == null).collect(Collectors.toList());//找出一級菜單的子菜單for (Menu menu : parentNodes) {menu.setChildren(list.stream().filter(m -> menu.getId().equals(m.getPid())).collect(Collectors.toList()));}return parentNodes;}}
2. 前端實(shí)現(xiàn)
2.1 User.vue
主要是表格多添加role字段,添加框增加角色選擇框
<template><div><div style="margin: 10px 0"><el-input style="width: 200px" placeholder="請輸入名稱" suffix-icon="el-icon-search" v-model="username"></el-input><el-input style="width: 200px" placeholder="請輸入地址" suffix-icon="el-icon-position" class="ml-5" v-model="address"></el-input><el-button class="ml-5" type="primary" @click="getList">搜索</el-button><el-button icon="el-icon-refresh" size="mini" @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><!-- <el-upload action="http://localhost:9000/user/import" :show-file-list="false" accept="xlsx" :on-success="handleImport" style="display: inline-block">-->
<!-- <el-button type="primary" class="ml-5">導(dǎo)入 <i class="el-icon-bottom"></i></el-button>-->
<!-- </el-upload>--><el-button type="success" @click="handleImport" class="ml-5">導(dǎo)入 <i class="el-icon-bottom"></i></el-button><el-button type="warning" @click="handleExport" class="ml-5">導(dǎo)出 <i class="el-icon-top"></i></el-button></div><el-table v-loading="loading" :data="tableData" border stripe :header-cell-class-name="headerBg" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="id" label="序號" width="140"></el-table-column><el-table-column prop="username" label="用戶名" width="140"></el-table-column><el-table-column prop="nickname" label="昵稱" width="140"></el-table-column><el-table-column prop="role" label="角色" width="140"><template v-slot="scope"><el-tag>{{ scope.row.role}}</el-tag></template></el-table-column><el-table-column prop="email" label="郵箱" width="200"></el-table-column><el-table-column prop="address" label="地址" width="140"></el-table-column><el-table-column prop="createTime" label="創(chuàng)建時(shí)間" width="140"></el-table-column><el-table-column label="操作" align="center"><template v-slot="scope"><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-paginationclass="page"@size-change="handleSizeChange"@current-change="handleCurrentChange":page-sizes="[5, 10]":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 label-width="80px" size="small"><el-form-item label="用戶名"><el-input v-model="form.username" autocomplete="off"></el-input></el-form-item><el-form-item label="昵稱"><el-input v-model="form.nickname" autocomplete="off"></el-input></el-form-item><el-form-item label="角色" ><el-select v-model="form.role" placeholder="請選擇" style="width: 100%"><el-optionv-for="item in roles":key="item.name":label="item.name":value="item.roleKey"></el-option></el-select></el-form-item><el-form-item label="郵箱"><el-input v-model="form.email" autocomplete="off"></el-input></el-form-item><el-form-item label="電話"><el-input v-model="form.phone" autocomplete="off"></el-input></el-form-item><el-form-item label="地址"><el-input v-model="form.address" 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><!-- 用戶導(dǎo)入對話框 --><el-dialog :title="upload.title" :visible.sync="upload.open" width="400px"><el-uploadref="upload":limit="1"accept=".xlsx, .xls":action="upload.url":disabled="upload.isUploading":on-progress="handleFileUploadProgress":on-success="handleFileSuccess":auto-upload="false"drag><i class="el-icon-upload"></i><div class="el-upload__text">將文件拖到此處,或<em>點(diǎn)擊上傳</em></div><div class="el-upload__tip" slot="tip"><el-link type="info" style="font-size: 16px;color:green" @click="importTemplate">下載模板</el-link></div><div class="el-upload__tip" style="color: red" slot="tip">提示:僅允許導(dǎo)入“xls”或“xlsx”格式文件!</div></el-upload><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitFileForm">確 定</el-button><el-button @click="upload.open = false">取 消</el-button></div></el-dialog></div></template><script>
export default {name: "User",data(){return {tableData: [],pageSize: 5,total: 0,pageNum: 1,username: '',address: '',collapseBtnClass: 'el-icon-s-fold',isCollapse: false,sideWidth: 200,logoTextShow: true,headerBg: 'headerBg',dialogFormVisible: false,form: {},// 遮罩層loading: true,// 選中數(shù)組ids: [],// 非單個(gè)禁用single: true,// 非多個(gè)禁用multiple: true,//用戶導(dǎo)入?yún)?shù)upload: {//是否顯示彈出層(用戶導(dǎo)入)open: false,//彈出層標(biāo)題(用戶導(dǎo)入)title: "",//是否禁用上傳// isUploading: false,//是否更新已經(jīng)存在的用戶數(shù)據(jù)//updateSupport: 0,//設(shè)置上傳的請求頭部//headers: "",//上傳的地址url: "http://localhost:9000/user/import",},roles: [],}},created() {this.getList();},methods: {getList(){this.loading = true;this.request.get('/user/page',{params: {pageNum: this.pageNum,pageSize: this.pageSize,username: this.username,address: this.address}}).then(res => {if(res.code === '200'){this.tableData = res.data.records;this.total = res.data.total;this.loading = false;}else{this.$message.error(res.msg)}})this.request.get('/role').then(res => {if(res.code === '200'){this.roles = res.data;}else{this.$message.error(res.msg)}})},handleSizeChange(val) {this.pageSize = val;},handleCurrentChange(val) {this.pageNum = val;this.getList();},// 多選框選中數(shù)據(jù)handleSelectionChange(selection) {this.ids = selection.map(item => item.id);this.single = selection.length != 1;this.multiple = !selection.length;},// 重置按鈕resetQuery(){this.username = undefined;this.address = undefined;this.getList();},// 新增handleAdd(){this.dialogFormVisible = true;this.form = {};},save(){this.request.post("/user",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();// 重新查詢數(shù)據(jù)const userId = row.id || this.ids;this.request.get('/user/'+userId).then(response => {this.form = response.data;this.dialogFormVisible = true;});},reset(){this.form.username = undefined;this.form.nickname = undefined;this.form.email = undefined;this.form.phone = undefined;this.form.address = undefined;},// 刪除handleDelete(row){let _this = this;const userIds = row.id || this.ids;this.$confirm('是否確認(rèn)刪除用戶編號為"' + userIds + '"的數(shù)據(jù)項(xiàng)?', '刪除用戶', {confirmButtonText: '確定',cancelButtonText: '取消',type: 'warning'}).then(() => {_this.request.delete("/user/"+userIds).then(res=>{if(res.code === "200" || res.code === 200){_this.$message.success("刪除成功")}else {_this.$message.error("刪除失敗")}this.getList();})}).catch(() => {});},// 導(dǎo)出handleExport(){window.open('http://localhost:9000/user/export');this.$message.success("導(dǎo)出成功");},// handleImport(){// this.$message.success('導(dǎo)入成功')// this.getList()// },handleImport(){this.upload.title = '用戶導(dǎo)入'this.upload.open = true},importTemplate(){this.$message.success("正在下載模版");window.open('http://localhost:9000/user/download')},//文件上傳處理handleFileUploadProgress(event,file,fileList){//this.upload.isUploading = true;this.loading = true;},//文件上傳成功處理handleFileSuccess(response,file,fileList){this.loading = false;this.upload.open = false;// this.upload.isUploading = false;this.$refs.upload.clearFiles();this.$message.success("導(dǎo)入成功");this.getList()},//提交上傳文件submitFileForm(){this.$refs.upload.submit();}}
}
</script><style scoped></style>
2.2 動(dòng)態(tài)菜單設(shè)計(jì)
2.2.1 Login.vue
在登錄成功的時(shí)候?qū)⒉藛未娴綖g覽器中
<template><div class="wrapper"><div style="margin: 200px auto; background-color: #fff; width: 350px; height: 300px; padding: 20px; border-radius: 10px"><div style="margin: 20px 0; text-align: center; font-size: 24px"><b>登 錄</b></div><el-form :model="user" :rules="rules" ref="userForm"><el-form-item prop="username"><el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-user" v-model="user.username"></el-input></el-form-item><el-form-item prop="password"><el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-lock" show-password v-model="user.password"></el-input></el-form-item><el-form-item style="margin: 10px 0; text-align: right"><el-button type="primary" size="small" autocomplete="off" @click="login">登錄</el-button><el-button type="warning" size="small" autocomplete="off" @click="$router.push('/register')">注冊</el-button></el-form-item></el-form></div></div>
</template><script>
export default {name: "Login",data() {return {user: {},rules: {username: [{ required: true, message: '請輸入用戶名', trigger: 'blur' },{ min: 3, max: 10, message: '長度在 3 到 5 個(gè)字符', trigger: 'blur' }],password: [{ required: true, message: '請輸入密碼', trigger: 'blur' },{ min: 1, max: 20, message: '長度在 1 到 20 個(gè)字符', trigger: 'blur' }],}}},methods: {login() {this.$refs['userForm'].validate((valid) => {if (valid) { // 表單校驗(yàn)合法this.request.post("/user/login", this.user).then(res => {if(res.code === 200 || res.code === '200') {localStorage.setItem('loginUser',JSON.stringify(res.data));localStorage.setItem("menus",JSON.stringify(res.data.menus));this.$router.push("/")this.$message.success("登錄成功")} else {this.$message.error(res.msg)}})} else {return false;}});}}
}
</script><style>
.wrapper {height: 100vh;background-image: linear-gradient(to bottom right, #FC466B , #3F5EFB);overflow: hidden;
}
</style>
2.2.2 Aside.vue
側(cè)邊欄動(dòng)態(tài)顯示菜單
<template><el-menu :default-openeds="['1', '3']" style="min-height: 100%; overflow-x: hidden"background-color="rgb(48, 65, 86)"text-color="#fff"active-text-color="#ffd04b":collapse-transition="false":collapse="isCollapse"router><div style="height: 60px; line-height: 60px; text-align: center"><img src="../assets/logo.png" alt="" style="width: 20px; position: relative; top: 5px; right: 5px"><b style="color: white" v-show="logoTextShow">后臺管理系統(tǒng)</b></div><div v-for="item in menus" :key="item.id"><!-- 一級菜單 --><div v-if="item.path"><el-menu-item :index="item.path"><template slot="title"><i :class="item.icon"></i><span slot="title">{{ item.name }}</span></template></el-menu-item></div><!-- 二級菜單 --><div v-else><el-submenu :index="item.id+''"><template slot="title"><i :class="item.icon"></i><span slot="title">{{ item.name }}</span></template><div v-for="subItem in item.children" :key="subItem.id"><el-menu-item :index="subItem.path"><template slot="title"><i :class="subItem.icon"></i><span slot="title">{{ subItem.name }}</span></template></el-menu-item></div></el-submenu></div></div></el-menu>
</template><script>
export default {name: "Aside",props: {isCollapse: Boolean,logoTextShow: Boolean},data() {return {menus: localStorage.getItem('menus') ? JSON.parse(localStorage.getItem('menus')) : []}},}
</script><style scoped></style>
2.3 動(dòng)態(tài)路由設(shè)計(jì)
為什么設(shè)置動(dòng)態(tài)路由,這是因?yàn)闆]有其他頁面權(quán)限的用戶也是可以訪問其他頁面
如下圖所示:
安其拉是普通用戶,只有主頁的菜單權(quán)限(自己設(shè)置的角色所擁有的菜單)
2.3.1 菜單表新增字段page_path
對應(yīng)每個(gè)頁面組件名稱
CREATE TABLE `sys_menu` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名稱',`path` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '路徑',`page_path` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '頁面路徑',`pid` int(11) DEFAULT NULL COMMENT '父級id',`icon` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '圖標(biāo)',`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述',`deleted` tinyint(1) DEFAULT '0' COMMENT '邏輯刪除',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC
2.3.2 路由設(shè)計(jì)
import Vue from 'vue'
import VueRouter from 'vue-router'
import Manage from '../views/Manage.vue'
import store from "@/store";Vue.use(VueRouter)
//定義一個(gè)路由對象數(shù)組
const routes = [{path: '/login',name: '登錄',component: () => import('../views/Login.vue')},{path: '/register',name: '注冊',component: () => import('../views/Register.vue')}]//使用路由對象數(shù)組創(chuàng)建路由實(shí)例,供main.js引用
const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})// 注意:刷新頁面會導(dǎo)致頁面路由重置
export const setRoutes = () => {const storeMenus = localStorage.getItem("menus");if (storeMenus) {// 獲取當(dāng)前的路由對象名稱數(shù)組const currentRouteNames = router.getRoutes().map(v => v.name)if (!currentRouteNames.includes('Manage')) {// 拼裝動(dòng)態(tài)路由const manageRoute = { path: '/', name: 'Manage', component: () => import('../views/Manage.vue'), redirect: "/home", children: [{ path: 'person', name: '個(gè)人信息', component: () => import('../views/Person.vue')},// { path: 'password', name: '修改密碼', component: () => import('../views/Password.vue')}] }const menus = JSON.parse(storeMenus)menus.forEach(item => {if (item.path) { // 當(dāng)且僅當(dāng)path不為空的時(shí)候才去設(shè)置路由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)}})}})// 動(dòng)態(tài)添加到現(xiàn)在的路由對象中去router.addRoute(manageRoute)}}
}// 重置我就再set一次路由
setRoutes()// 路由守衛(wèi)
// router.beforeEach((to, from, next) => {
// localStorage.setItem('currentPathName',to.name); // 設(shè)置當(dāng)前的路由名稱,為了在Header組件中去使用
// store.commit('setPath') // 觸發(fā)store的數(shù)據(jù)更新
// next() // 放行路由
// })export default router
2.3.3 登錄界面Login.vue設(shè)置路由
改動(dòng)登錄頁面在成功登錄時(shí),設(shè)置路由
// 導(dǎo)入
import {setRoutes} from "@/router";// 當(dāng)?shù)卿洺晒r(shí),同時(shí)設(shè)置路由
localStorage.setItem("user",JSON.stringify(res.data)); //存儲用戶信息到瀏覽器
localStorage.setItem("menus",JSON.stringify(res.data.menus)); //存儲菜單到瀏覽器
setRoutes();
this.$router.push("/");
this.$message.success("登錄成功");
總結(jié)
- 本篇主要講解動(dòng)態(tài)菜單和動(dòng)態(tài)路由的設(shè)計(jì)與實(shí)現(xiàn)
寫在最后
如果此文對您有所幫助,請帥戈靚女們務(wù)必不要吝嗇你們的Zan,感謝!!不懂的可以在評論區(qū)評論,有空會及時(shí)回復(fù)。
文章會一直更新