PanJiaChen / vue-element-admin

:tada: A magical vue admin https://panjiachen.github.io/vue-element-admin
MIT License
87.11k stars 30.4k forks source link

router.addRoutes 无效 #2370

Open zhuxiaokang0223 opened 5 years ago

zhuxiaokang0223 commented 5 years ago

Question(提问)

基于vue-admin-template,使用router.addRoutes动态加载菜单,查看控制台,无报错信息,console.info打印菜单有数据。但是左侧菜单栏没有动态变更。  
请问怎么解决? 谢过......

Steps to reproduce(问题复现步骤)

Screenshot or Gif(截图或动态图)

Link to minimal reproduction(最小可在线还原demo)

router.beforeEach:

router.beforeEach(async(to, from, next) => {

  NProgress.start()

  document.title = getPageTitle(to.meta.title)
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else { 
      const hasGetUserInfo = store.getters.name   
      const menuList = store.getters.routes && store.getters.routes.length > 0 
      if (hasGetUserInfo && menuList) {
        next()
      } else {
        try { 
          // 获取用户信息
          await store.dispatch('user/getInfo')
          // 动态菜单
          const accessRoutes = await store.dispatch('permission/generateRoutes')
         // 这里打印到控制台,是有数据的
          console.info(accessRoutes)
          router.addRoutes(accessRoutes)

          next({ ...to, replace: true }) 
        } catch (error) {
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})
router.afterEach(() => {
  // 完成进度条
  NProgress.done()
})

动态菜单测试代码:


import {constantRoutes } from '@/router'

import Layout from '@/layout'

const state = {
    routes: [],
    addRoutes: []
  }

const mutations = {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    }
  }

const actions = {
    generateRoutes({ commit }) {
      return new Promise(resolve => {
        let accessedRoutes = formatRoutes

        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes) 
      })
    }
  }

export const formatRoutes =  [
    {
      path: '/ccc',
      component: Layout,
      children: [
        {
          path: 'ccc',
          name: 'ccc',
          component: () => import('@/views/form/index'),
          meta: { title: 'ffff', icon: 'form' }
        }
      ]
    },
    { path: '*', redirect: '/404', hidden: true }
  ]

  export default {
    namespaced: true, 
    state,
    mutations,
    actions
  }

Other relevant information(格外信息)

wangyegg1989 commented 5 years ago

getMenuList().then(res => { accessedRouters = convertRouter(res.data.menuLeftTree) store.dispatch('permission/generateRoutes', accessedRouters).then(result => { router.addRoutes(result) }) })

yoodz commented 4 years ago

你好,请问这个问题怎么解决的?

chazex commented 4 years ago

同问,解决方式是什么呢?

chazex commented 4 years ago

修改layout/components/Sidebar/index.vue ,遍历路由生成菜单的时候不要使用siderbar,要使用permission_routes。 如果没看懂的话,可以vue-element-admin模板中的该文件,对比一下,就明白了。

w22296437978 commented 4 years ago

问题解决了,但是刷新一下404

yoodz commented 4 years ago

问题解决了,但是刷新一下404

constantRoutes 里的404页面放到最后试一试。总之是 404页面要最后导入。

w22296437978 commented 4 years ago

是最后一个, 盲猜刷新后先找的路由后进行的权限路由的加载 image

w22296437978 commented 4 years ago

好了 404也解决了,放到asyncRoutes路由的最后面

xiongshj commented 4 years ago

好了 404也解决了,放到asyncRoutes路由的最后面

我写的刷新后 404 的问题解决了,谢谢这个答案!

wdsjxh commented 3 years ago

感谢各位大佬,帮我解决问题了

sxxsc555 commented 2 years ago

感谢各位大佬,帮我解决问题了

bigger-boss commented 2 months ago

我焯,我找这答案找得好苦啊