目录

遇到问题

1. 修改router/index.js

2. 修改 store文件夹下的

2.1 增加 modules/permission.js

2.2 增加modules/tagsViews.js

2.3 修改modules/user.js

2.4 修改getter.js

2.5 修改index.js

遇到问题

1.当出现循环刷新页面,不断进行请求时,检查配置的动态菜单 权限是否配置正确;切换身份导致菜单不发生变化;

2. Duplicate named routes definition [菜单配置不对]

由于我的配置的菜单下 只有一个菜单,我是将【1】 里的 roles配置 加到 【2】 上导致 登陆时封装菜单错误,不断刷新页面,登陆成功后切换身份也导致菜单显示不对。

3.问题描述 配置好动态路由后,在动态路由的路径刷新页面报 ,第一次点击是好的,一旦刷新页面出以下问题

Error in beforeCreate hook: "RangeError: Maximum call stack size exceeded"

RangeError: Maximum call stack size exceeded

Error in render: "TypeError: Cannot read properties of undefined (reading 'matched')"

Vue-router-3.0.1 使用router.addRoutes()设置动态路由,页面刷新后无效 - #25 by BruceChoo7 - 中文 - Vue Forumhttps://forum.vuejs.org/t/vue-router-3-0-1-router-addroutes/33181/25

解决办法

初始路由不要加重定向到404路由,否则beforeEach时地址已经变成/404了,将 404 添加到动态地址中

1. 修改router/index.js

增加

export const asyncRoutes = [{path: '/qw',component: Layout,name: 'qw',meta: { title: '企微微信', icon: 'el-icon-files',roles: ['admin', 'dev']  },children: [{path: 'msg',name: 'msg',component:  () => import('@/views/qw/msg'),meta: { title: '企微消息素材管理', icon: 'el-icon-document'}}]}
]

2. 修改 store文件夹下的

2.1 增加 modules/permission.js

import { asyncRoutes, constantRoutes } from '@/router'/*** Use meta.role to determine if the current user has permission* @param roles* @param route*/
function hasPermission(roles, route) {if (route.meta && route.meta.roles) {return roles.some(role => route.meta.roles.includes(role))} else {return true}
}/*** Filter asynchronous routing tables by recursion* @param routes asyncRoutes* @param roles*/
export function filterAsyncRoutes(routes, roles) {const res = []routes.forEach(route => {const tmp = { ...route }if (hasPermission(roles, tmp)) {if (tmp.children) {tmp.children = filterAsyncRoutes(tmp.children, roles)}res.push(tmp)}})return res
}const state = {routes: [],addRoutes: []
}const mutations = {SET_ROUTES: (state, routes) => {state.addRoutes = routesstate.routes = constantRoutes.concat(routes)}
}const actions = {generateRoutes({ commit }, roles) {return new Promise(resolve => {let accessedRoutesif (roles.includes('admin')) {accessedRoutes = asyncRoutes || []} else {accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)}commit('SET_ROUTES', accessedRoutes)resolve(accessedRoutes)})}
}export default {namespaced: true,state,mutations,actions
}

2.2 增加modules/tagsViews.js

const state = {visitedViews: [],cachedViews: []
}const mutations = {ADD_VISITED_VIEW: (state, view) => {if (state.visitedViews.some(v => v.path === view.path)) returnstate.visitedViews.push(Object.assign({}, view, {title: view.meta.title || 'no-name'}))},ADD_CACHED_VIEW: (state, view) => {if (state.cachedViews.includes(view.name)) returnif (!view.meta.noCache) {state.cachedViews.push(view.name)}},DEL_VISITED_VIEW: (state, view) => {for (const [i, v] of state.visitedViews.entries()) {if (v.path === view.path) {state.visitedViews.splice(i, 1)break}}},DEL_CACHED_VIEW: (state, view) => {const index = state.cachedViews.indexOf(view.name)index > -1 && state.cachedViews.splice(index, 1)},DEL_OTHERS_VISITED_VIEWS: (state, view) => {state.visitedViews = state.visitedViews.filter(v => {return v.meta.affix || v.path === view.path})},DEL_OTHERS_CACHED_VIEWS: (state, view) => {const index = state.cachedViews.indexOf(view.name)if (index > -1) {state.cachedViews = state.cachedViews.slice(index, index + 1)} else {// if index = -1, there is no cached tagsstate.cachedViews = []}},DEL_ALL_VISITED_VIEWS: state => {// keep affix tagsconst affixTags = state.visitedViews.filter(tag => tag.meta.affix)state.visitedViews = affixTags},DEL_ALL_CACHED_VIEWS: state => {state.cachedViews = []},UPDATE_VISITED_VIEW: (state, view) => {for (let v of state.visitedViews) {if (v.path === view.path) {v = Object.assign(v, view)break}}}
}const actions = {addView({ dispatch }, view) {dispatch('addVisitedView', view)dispatch('addCachedView', view)},addVisitedView({ commit }, view) {commit('ADD_VISITED_VIEW', view)},addCachedView({ commit }, view) {commit('ADD_CACHED_VIEW', view)},delView({ dispatch, state }, view) {return new Promise(resolve => {dispatch('delVisitedView', view)dispatch('delCachedView', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delVisitedView({ commit, state }, view) {return new Promise(resolve => {commit('DEL_VISITED_VIEW', view)resolve([...state.visitedViews])})},delCachedView({ commit, state }, view) {return new Promise(resolve => {commit('DEL_CACHED_VIEW', view)resolve([...state.cachedViews])})},delOthersViews({ dispatch, state }, view) {return new Promise(resolve => {dispatch('delOthersVisitedViews', view)dispatch('delOthersCachedViews', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delOthersVisitedViews({ commit, state }, view) {return new Promise(resolve => {commit('DEL_OTHERS_VISITED_VIEWS', view)resolve([...state.visitedViews])})},delOthersCachedViews({ commit, state }, view) {return new Promise(resolve => {commit('DEL_OTHERS_CACHED_VIEWS', view)resolve([...state.cachedViews])})},delAllViews({ dispatch, state }, view) {return new Promise(resolve => {dispatch('delAllVisitedViews', view)dispatch('delAllCachedViews', view)resolve({visitedViews: [...state.visitedViews],cachedViews: [...state.cachedViews]})})},delAllVisitedViews({ commit, state }) {return new Promise(resolve => {commit('DEL_ALL_VISITED_VIEWS')resolve([...state.visitedViews])})},delAllCachedViews({ commit, state }) {return new Promise(resolve => {commit('DEL_ALL_CACHED_VIEWS')resolve([...state.cachedViews])})},updateVisitedView({ commit }, view) {commit('UPDATE_VISITED_VIEW', view)}
}export default {namespaced: true,state,mutations,actions
}

2.3 修改modules/user.js

import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router,{ resetRouter } from '@/router'const getDefaultState = () => {return {token: getToken(),name: '',group:'',roles:'',avatar: ''}
}const state = getDefaultState()const mutations = {RESET_STATE: (state) => {Object.assign(state, getDefaultState())},SET_TOKEN: (state, token) => {state.token = token},SET_NAME: (state, name) => {state.name = name},SET_GROUP: (state, group) => {state.group = group},SET_ROLES: (state, roles) => {state.roles = roles},SET_AVATAR: (state, avatar) => {state.avatar = avatar}
}const actions = {// user loginlogin({ commit }, userInfo) {const { username, password } = userInforeturn new Promise((resolve, reject) => {login({ username: username.trim(), password: password }).then(response => {const { data } = responsecommit('SET_TOKEN', data.token)// commit('SET_NAME', data.username)// commit('SET_GROUP', data.group)// commit('SET_ROLES', data.role)setToken(data.token)resolve()}).catch(error => {reject(error)})})},// get user infogetInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo(state.token).then(response => {console.log(response)const { data } = responseif (!data) {reject('Verification failed, please Login again.')}console.log(data)const { username, avatar,group,roles } = datacommit('SET_NAME', username)commit('SET_AVATAR', avatar)commit('SET_GROUP', group)commit('SET_ROLES', roles)resolve(data)}).catch(error => {reject(error)})})},// user logoutlogout({ commit, state }) {return new Promise((resolve, reject) => {removeToken() // must remove  token  firstresetRouter()commit('RESET_STATE')resolve()// logout(state.token).then(() => {//   removeToken() // must remove  token  first//   resetRouter()//   commit('RESET_STATE')//   resolve()// }).catch(error => {//   reject(error)// })})},// remove tokenresetToken({ commit }) {return new Promise(resolve => {removeToken() // must remove  token  firstcommit('RESET_STATE')resolve()})},// dynamically modify permissionsasync changeRoles({ commit, dispatch }, role) {const token = role + '-token'commit('SET_TOKEN', token)setToken(token)const { roles } = await dispatch('getInfo')resetRouter()// generate accessible routes map based on rolesconst accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })// dynamically add accessible routesrouter.addRoutes(accessRoutes)// reset visited views and cached viewsdispatch('tagsView/delAllViews', null, { root: true })}
}export default {namespaced: true,state,mutations,actions
}

2.4 修改getter.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,permission_routers: state => state.permission.routes,
}
export default getters

2.5 修改index.js

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'Vue.use(Vuex)// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {// set './app.js' => 'app'const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')const value = modulesFiles(modulePath)modules[moduleName] = value.defaultreturn modules
}, {})const store = new Vuex.Store({modules,getters
})export default store

2.3 修改permission.js

主要修改红框中的

import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import { getToken } from "@/utils/auth"; // get token from cookie
import getPageTitle from "@/utils/get-page-title";NProgress.configure({ showSpinner: false }); // NProgress Configurationconst whiteList = ["/login", "/funnelAnalyse", "/retentionAnalyse"]; // no redirect whitelistrouter.beforeEach(async (to, from, next) => {// start progress barNProgress.start();// set page titledocument.title = getPageTitle(to.meta.title);// determine whether the user has logged inconst hasToken = getToken();if (hasToken) {if (to.path === "/login") {// if is logged in, redirect to the home pagenext({ path: "/" });NProgress.done();} else {const hasRoles = store.getters.roles && store.getters.roles.length > 0if (hasRoles) {next();} else {try {// get user info// await store.dispatch("user/getInfo");// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']const { roles } = await store.dispatch('user/getInfo')// generate accessible routes map based on rolesconst accessRoutes = await store.dispatch('permission/generateRoutes', roles)// dynamically add accessible routesrouter.addRoutes(accessRoutes)// hack method to ensure that addRoutes is complete// set the replace: true, so the navigation will not leave a history recordnext({ ...to, replace: true })// next();} catch (error) {// remove token and go to login page to re-login// await store.dispatch("user/resetToken");await store.dispatch('user/resetToken')Message.error('Has Error')next(`/login?redirect=${to.path}`)NProgress.done()}}}} else {/* has no token*/if (whiteList.indexOf(to.path) !== -1) {// in the free login whitelist, go directlynext();} else {// other pages that do not have permission to access are redirected to the login page.next(`/login?redirect=${to.path}`);NProgress.done();}}
});router.afterEach(() => {// finish progress barNProgress.done();
});

参考

vue-admin-template 添加权限控制路由功能_fiskeryang的专栏-CSDN博客vue-element-template添加权限控制路由功能vue-element-template添加权限控制路由功能1、 变更@/router/index.js2、添加@/store/modules/permission.js3、改造数据库与实体4、@/store/modules/user.js5、更新 getter.js 和 index.js6、变更 @/permission.jsvue-element-template添加权限控制路由功能vue-element-template 是没有实现路由权https://blog.csdn.net/fiskeryang/article/details/112358889

Vue 增加动态路由功能 【在原有系统上增加】相关推荐

  1. vue将每个路由打包成html,Ant Design Vue pro 动态路由的实现和打包

    Ant Design Vue pro 动态路由的实现和打包 Ant Design Vue pro 动态路由的实现和打包 配置路由权限 在config文件夹下router.config.js中配置路由权 ...

  2. Spring Cloud Alibaba 集成 Gateway 实现动态路由功能

    文章目录 1 摘要 2 核心 Maven 依赖 3 名词释义 4 Gateway 动态路由原理 5 数据库表 6 核心代码 6.1 配置信息 6.2 路由实体类 6.3 本地路由数据库持久层(DAO/ ...

  3. 路由原理及vue实现动态路由

    路由原理 在前端开发中,路由通常用于实现 SPA 应用程序,即在一个页面中切换不同的内容或页面,而不需要重新加载整个页面.路由的实现原理是通过监听 URL 的变化,然后根据不同的 URL 加载不同的内 ...

  4. vue admin 动态路由权限管理

    主要思路 通过后端接口返回数据 进行判断 (通过后端实现的权限管理有许多种),在这里 我们主要通过 关键字即匹配前端路由meta.menu值来实现权限管理通常会把路由权限列表存至vux中 箭头所指的便 ...

  5. vue 实现动态路由

    1.什么是动态路由? 2.动态路由的好处 3.动态路由如何实现 1.什么是动态路由? 动态路由,动态即不是写死的,是可变的.我们可以根据自己不同的需求加载不同的路由,做到不同的实现及页面的渲染.动态的 ...

  6. 【vue】---动态路由传值

    vue中的路由传值动态路由1.在定义路由的时候通过/:属性的方式来定义传递参数的属性2.在进行路由跳转的时候通过/值得方式进行传递数据3.在需要接收参数的组件中通过this.$route.params ...

  7. Nginx部署Vue项目动态路由刷新404

    目录 前言 第一次 第二次 前言 记录下Nginx部署Vue项目刷新404的解决方案,遇到了两次,route用的是history路由模式,动态路由: {path: '/article/:blogId' ...

  8. vue的动态路由(登录之后拿到动态路由通过addRouters()动态添加路由)

    登录后我们拿到路由动态路由,后端传的数据可能为这个 {path: '/index',meta: {title: '首页',icon: 'icon-shouye',tab_index: 0, //给头部 ...

  9. vue实现动态路由一步到位

    最近在写vue项目,需要由后台传来当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由),就是配置vue动态路由啦. 由于错信了一些网上的文章:(,导致在这个问题上耗费了不少时间,想想,还 ...

最新文章

  1. GeoTrust 企业(OV)型 SSL证书
  2. python中的seth函数_Python入门——turtle库的使用
  3. python while循环和双重循环
  4. 浅谈c/c++typedef和#define区别[转]
  5. exxi6.7如何传文件到win7_比QQ直传快100倍!它让PC、安卓、iPhone光速互传文件
  6. mysql udb_MySQL InnoDB的一些参数说明
  7. [vue-cli]在使用vue-cli开发vue项目时,自动刷新页面的原理你了解吗?
  8. 鸿蒙轻内核虚拟内存基础知识:虚拟内存进程空间编号
  9. 重要性采样(Importance Sampling)简介和简单样例实现
  10. 只十分钟,唾手可得的工作机会就被我搞砸了!
  11. android的log.v,Android Log.v(),Log.d(),Log.i(),Log.w(),Log.e() - 何时使用每一个?
  12. 常用SFTP工具类(多个公用方法)
  13. java 防止js注入----ESAPI结合Top10安全开发实战
  14. 在夕阳再晨的日子里(二)----掌管市场部的岁月之合作团队与社区的拓展
  15. 网络在线播放ASF格式流媒体文件的制作(转)
  16. 如何定制allure报告的logo
  17. 无论如何,我喜欢过你
  18. java around_java - 使用Spring AOP时,在单个连接点上具有参数绑定的多个Around建议会导致错误 - 堆栈内存溢出...
  19. Windows11之Vim超详细下载安装与使用教程
  20. 密码学系列之七:数字签名

热门文章

  1. 贪心算法简单实践 -- 分糖果、钱币找零、最多区间覆盖、哈夫曼编解码
  2. bzoj 3598 [ Scoi 2014 ] 方伯伯的商场之旅 ——数位DP
  3. vmware虚拟机启动centOs黑屏
  4. springboot添加多数据源连接池并配置Mybatis
  5. python框架之Flask基础篇(一)
  6. SparkSQL 与 Spark Core的关系
  7. 原创:去繁存简,回归本源:微信小程序公开课信息分析《一》
  8. android4.4 添加快捷开关(以截屏为例)
  9. Linux 内核进程管理之进程ID
  10. 标准C++中的string类的用法总结