https://www.jianshu.com/p/917a21e5f5e1
需求:用戶登錄后獲取相應的菜單權限,這里已知后台獲取的菜單樹
這里介紹兩種方式:
1、根據從后台獲取的路由路徑動態注冊路由(import到項目),在前端配置菜單權限時需提交路由的路徑給后台;
2、前端代碼中將所有的路由路徑注冊好(全部import到項目),由於路由全部注冊好了,根據后台返回的菜單顯示即可;但這樣在地址欄輸入路由還是可以訪問到,所以前端配置菜單權限時需要給后台提交相應的接口權限,用戶登錄后沒有這個菜單的接口權限則輸入地址欄也無權訪問,保證正確性。
兩種方式的區別:
第一種是通過后台獲取菜單之后去注冊路由,那么地址欄輸入路由就會報404
第二種是全部注冊好路由,地址欄輸入不會報404,這時候需要控制接口權限
方式一:動態注冊路由
loadingRoutes.js
/*
動態注冊路由
頁面全在views文件夾下
如:
import page1 from './views/page1.vue'
import page2 from './views/page/page2.vue'
*/
export default (name) => () => import(`@/views/${name}.vue`)
menuUtils.js
// 引入注冊路由方法
import loadingRoutes from './loadingRoutes'
export default (routers, data) => {
//轉換服務端菜單數據,拿到自己想要的字段,比如這里的路由路徑component (或者其他的key)
generaMenu(routers, data)
}
function generaMenu(routers, data) {
if (data) {
data.forEach((item) => {
//這里在和后台規定如果是按鈕權限component字段為'/' ,權限按鈕為彈出框,沒有路由
if (item.path == "/") {
return false;
}
let menu = Object.assign({}, item);
if (menu.component == "home") {
menu.component = require("@/views/Home.vue");
menu = Object.assign({redirect: item.children?item.children[0].path:"/main"}, menu);
} else {
// 注冊加載相應路由
menu.component = loadingRoutes (menu.component)
}
//有子菜單
if (item.leaf == "true") {
menu.children = [];
generaMenu(menu.children, item.children)
}
// 將菜單push進路由
routers.push(menu)
})
}
}
home.vue
created() {
//這里沒有直接使用this.$router.options.routes,是因為addRoute的路由規則,在這里this.$router.options.routes獲取不到
//另外在開發的時候,可能由於是熱部署,也會不斷重復的給nodes添加元素,造成導航條有重復的,簡單解決,可以設置一個開關
let isLoadNodes = sessionStorage.getItem('isLoadNodes');
if (!isLoadNodes) {
let menuInfo = sessionStorage.getItem('menuInfo');
if (menuInfo) {
let data = JSON.parse(window.sessionStorage.getItem('menuInfo'));
this.nodes.push(...data);
sessionStorage.setItem('isLoadNodes', 'true')
} else {
//this.$api.getMenus({roleId: getCookie('property_roleId')}).then((res) => {
this.$api.getMenus({roleId: sessionStorage.getItem('property_roleId')}).then((res) => {
if (this.$util.checkCode(this, res)) {
this.nodes.push(...res.data);
sessionStorage.setItem('isLoadNodes', 'true')
}
});
}
}
},
routes.js
const router = new Router({
mode: 'history',
routes
});
// 引入MenuUtils
import MenuUtils from '@/scripts/common/MenuUtils'
let data = JSON.parse(window.sessionStorage.getItem('menuInfo'))
if (data) {
//這里是防止用戶手動刷新頁面,整個app要重新加載,動態新增的路由,會消失,所以需要重新add一次
// 或者通過vuex保存菜單,重新賦值 這里不做說明
let routes = [];
MenuUtils(routes, data);
router.addRoutes(routes);
window.sessionStorage.removeItem('isLoadNodes');
}
方式二:注冊好全部路由,后台控制接口訪問權限
方式二其實更簡單,由於路由全部注冊好了,通過后台返回的菜單樹進行顯示即可,這里不做詳細說明。
如果采用vuex保存菜單,注意刷新的時候重新獲取菜單。
本篇文章偏向於說明動態獲取菜單的思想,有什么不足的地方或疑問歡迎指出來,謝謝大家~
作者:我追求的小世界
鏈接:https://www.jianshu.com/p/917a21e5f5e1
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。