vue.js動態獲取菜單


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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM