第七次课:动态菜单-前端
分类: springboot 专栏: 在线教育项目实战 标签: 动态菜单-前端页面
2023-05-11 12:03:02 1134浏览
参考:https://juejin.cn/post/7002874867167019045
修改路由文件
位置:src\router\index.js
export const constantRoutes = [
{ path: '/login', component: () => import('@/views/login/index'), hidden: true },
{ path: '/404', component: () => import('@/views/404'), hidden: true },
{
path: '/',
component: Layout,
redirect: '/dashboard',
name: '首页',
hidden: true,
children: [{
path: 'dashboard',
component: () => import('@/views/dashboard/index')
}]
},
]
const router = new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
}
)
export default router修改src\store\modules\user.js
const user = {
state: {
token: getToken(),
name: '',
avatar: '',
roles: [],//角色权限控制按钮显示
menus: [] // 菜单权限
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_MENUS: (state, menus) => {
state.menus = menus // 菜单权限
}
},
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
login(username, userInfo.password).then(response => {
const data = response.data
console.log("data==============")
console.log(data)
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const data = response.data
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
} else {
reject('getInfo: roles must be a non-null array !')
}
/**
* 获取异步路由后加入404路由能解决刷新后【丢失路由跳转404页面】问题
(因为异步获取路由优先级比静态路由表低,导致404路由在异步添加的路由之前)
*/
const menus= data.menus
menus.push( {
'path': '*',
'redirect': '/404',
'hidden': 'true'
})
commit('SET_NAME', data.username)
commit('SET_AVATAR', data.avatar)
commit('SET_MENUS', data.menus) // 菜单权限
resolve(response)
}).catch(error => {
reject(error)
})
})
},主要改的地方:



修改getters.js存储信息
位置:src\store\getters.js
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
roles: state => state.user.roles,// 角色权限控制按钮
menus: state => state.user.menus, // 菜单权限
}
export default getters修改permission.js的vuex导航守卫
自学:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
位置:src\permission.js
注意:引入Layout

import router from './router'
import store from './store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css'// Progress 进度条样式
import { Message } from 'element-ui'
import { getToken } from '@/utils/auth' // 验权
import Layout from '@/views/layout/Layout'// 引入Layout
const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
//to 目标菜单
//form 源头
//next 放行
NProgress.start()//进度条
if (getToken()) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
} else {
if (store.getters.roles.length === 0) {
store.dispatch('GetInfo').then(res => { //请求 用户基本信息的接口
//就可以拿到当前登录者的菜单
// **在这里做动态路由**
if (store.getters.menus.length < 1) {
global.antRouter = []
next()
}
//store.getters.menus是长啥样???
const menus = filterAsyncRouter(store.getters.menus) // 过滤路由
router.addRoutes(menus) // 动态添加路由
global.antRouter = menus // 将路由数据传递给全局变量,做侧边栏菜单渲染工作
next({ ...to, replace: true })
}).catch((err) => {
store.dispatch('FedLogOut').then(() => {
Message.error(err || 'Verification failed, please login again')
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
NProgress.done()//进度条结束
}
}
})
function filterAsyncRouter(asyncRouterMap) { // 遍历后台传来的路由字符串,转换为组件对象
try {
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'Layout') { // Layout组件特殊处理
route.component = Layout
} else {
const component = route.component
route.component = resolve => {
require(['@/views' + component + '.vue'], resolve)
}
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
} catch (e) {
console.log(e)
}
}
router.afterEach(() => {
NProgress.done() // 结束Progress
})
替换成动态路由
位置:src\views\layout\components\Sidebar\index.vue
routes() {
return this.$router.options.routes.concat(global.antRouter) // 新路由连接
},json-server学习
作为一个前端开发工程师,在后端还没有ready的时候,不可避免的要使用mock的数据。很多时候,我们并不想使用简单的静态数据,而是希望自己起一个本地的mock-server来完全模拟请求以及请求回来的过程。json-server是一个很好的可以替我们完成这一工作的工具。我们只需要提供一个json文件,或者写几行简单的js脚本就可以模拟出RESTful API的接口。
参考文章:https://blog.csdn.net/weixin_40817115/article/details/81237128
准备工作
1.安装json-server
npm install -g json-server
2.查看版本
json-server -v
3.新建一个json文件db.json
{
"student": [
{
"id": 1,
"stuno": "20190115",
"name": "张三",
"phone": "15336514240",
"score": {
"yuwen": 80,
"shuxue": 50
}
},
{
"id": 2,
"stuno": "20190116",
"name": "李四",
"phone": "15336514250",
"score": {
"yuwen": 50,
"shuxue": 90
}
},
{
"id": 3,
"stuno": "20190117",
"name": "王五",
"phone": "15336515240",
"score": {
"yuwen": 50,
"shuxue": 100
}
},
{
"stuno": "20190115",
"name": "王健林",
"phone": "15336515241",
"score": {
"yuwen": 90,
"shuxue": 50
},
"id": 5
},
{
"stuno": "20190118",
"name": "马云",
"phone": "15336515241",
"score": {
"yuwen": 90,
"shuxue": 50
},
"id": 6
}
]
}4.启动json-server
json-server db.json

增:添加一条学生的记录
http://localhost:3000/student/
{
"stuno": "20190118",
"name": "马云",
"phone": "15336515241",
"score": {
"yuwen":90,
"shuxue": 50
}
}
删除一条记录
http://localhost:3000/student/4

修改一条记录
修改id为5的学生信息
发送put请求
http://localhost:3000/student/5

查id为1的学生信息
发送get请求http://localhost:3000/student/1

查李四的信息
http://localhost:3000/student/?name=李四

查询语文成绩大于等于80的学生
http://localhost:3000/student/?score.yuwen_gte=80

查询所有学生的信息和成绩
get请求http://localhost:3000/student/

模拟后台user接口
为了方便调试,可以先把响应拦截器的代码屏蔽
位置:src\utils\request.js

准备db.json文件
{
"data":{
"username":"admin",
"roles":[
{
"id":null,
"roleName":"超级管理员",
"roleCode":"ROLE_admin",
"remark":null,
"isDeleted":null,
"eduCreate":null,
"eduModified":null
}
],
"avatar":"http://vue.ruoyi.vip/static/img/profile.473f5971.jpg",
"menus":[
{
"redirect":"noredirect",
"path":"/acl",
"component":"Layout",
"hidden":false,
"children":[
{
"path":"user/list",
"component":"/acl/user/list",
"hidden":false,
"meta":{
"title":"后台用户"
},
"name":"name_3"
},
{
"path":"role/list",
"component":"/acl/role/list",
"hidden":false,
"meta":{
"title":"角色管理"
},
"name":"name_4"
},
{
"path":"menu/list",
"component":"/acl/menu/list",
"hidden":false,
"meta":{
"title":"菜单管理"
},
"name":"name_5"
}
],
"meta":{
"icon":"example",
"title":"权限管理"
},
"name":"name_2"
},
{
"redirect":"noredirect",
"path":"/teacher",
"component":"Layout",
"hidden":false,
"children":[
{
"path":"/list",
"component":"/teacher/list",
"hidden":false,
"meta":{
"title":"讲师列表"
},
"name":"name_7"
},
{
"path":"/save",
"component":"/teacher/save",
"hidden":false,
"meta":{
"title":"添加讲师"
},
"name":"name_8"
}
],
"meta":{
"icon":"example",
"title":"讲师管理"
},
"name":"name_6"
}
]
}
}
修改接口
位置:src\api\login.js
export function getInfo(token) {
return request({
url: 'http://localhost:3000/data',
// url: '/acl/user/info',
method: 'get',
params: { token }
})
}特别注意
注意: redirect: 'noredirect',
这里的noredirect不能写成noRedirect,官网写的是错的……

另外就是刷新当前页面要么是空白页要么是404,烦人的很
解决如下:

好博客就要一起分享哦!分享海报
此处可发布评论
评论(3)展开评论
您可能感兴趣的博客

新业务
springboot学习
ssm框架课
vue学习
【带小白】java基础速成