vue-element-admin vue设置动态路由 刷新页面后出现跳转404页面Bug 解决方法

20 篇文章 1 订阅
12 篇文章 0 订阅

做项目时遇到的这个bug,因为除了跳404之外也没太大影响,之前就一直放着没管,现在项目基本功能实现了,转头处理了一下,现在在这里记录一下解决方法

这个bug的具体情况是:设置了动态路由之后,不同的用户登录之后显示了不同的侧边栏,在侧边栏点击菜单,渲染对应路由页面没有任何问题,但是在动态路由上当我刷新浏览器时会出现404(这种情况只出现在动态路由上,静态路由刷新没问题)。

动态路由设置不成功的可以看我之前的文章:vue-element-template 设置权限管理配置文件 \ vue用户权限管理_vue template设置-CSDN博客

解决方法一

        由于通配路由需要放在整个路由的最后,所以不能放在asyncRouterMap的最后,但是也不能直接放在constantRoutes的最后,因为在动态路由在刷新时会跳转到404,因为刷新是动态路由还没加载进来,但是页面已经进行了跳转,找不到匹配的路由,最后会去到通配路由。

解决方法:

把下面这个路由从constantRoutes的最后一行转移到asyncRoutes的最后一行即可!

// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }

解决方法二:

        在使用的过程中,加入权限模块后,刷新后权限控制的页面就默认跳转到404页面了,原因是权限控制的路由模块是动态添加进去的,而我的404监听路由是在默认路由里面的,优先级比动态路由要高,所以刷新后默认先被404接管了,改一下,把404监听路由注释掉需要手动在动态路由加载后,再把通配路由加上去,所以有了解决方法二
解决方法二:
src/router/index.js,去静态路由里把404路由注释掉

// 静态路由,所有人可见
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    // hidden为true表示在侧边栏不显示
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    // 二级路由
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页', icon: 'dashboard' }
    }]
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  // 把这里注释掉,或者删掉
  // { path: '*', redirect: '/404', hidden: true }
]

然后修改文件: /src/permission.js,具体位置是下面这段代码中注释后面两行

const res = await store.dispatch('user/getInfo')
let roles = res.info.auth_list
const accessRoutes = await store.dispatch('permission/GenerateRoutes', roles)
let old = JSON.parse(JSON.stringify(router.options))
router.addRoutes(accessRoutes)

// 在这动态添加最后的通配路由,确保先有动态路由、再有通配路由,解决动态路由刷新会跳转到404问题
let lastRou = [{ path: '*', redirect: '/404' }]
router.addRoutes(lastRou)

let newr = JSON.parse(JSON.stringify(router.options))
next({ ...to, replace: true })

/src/permission.js完整代码【可能每个人的不同,建议对照修改而不是复制】

// 引入路由器router
import router from './router'
// 引入仓库
import store from './store'
// 引入ele的提示组件
import { Message } from 'element-ui'
// 引入交互进度条
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
// 从cookie中获取token,登录了就有cookie
import { getToken } from '@/utils/auth' // get token from cookie
// 得到页面的title
import getPageTitle from '@/utils/get-page-title'

// 配置nprogress
NProgress.configure({ showSpinner: false }) // NProgress Configuration

// 白名单,不需要登录就能进入的路由
const whiteList = ['/login'] // no redirect whitelist

// 全局前置路由守卫
router.beforeEach(async(to, from, next) => {
  //开启进度条
  NProgress.start()

  //给页面的title赋值
  document.title = getPageTitle(to.meta.title)

  // 从cookie中拿到token,有的话就放行,determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done()
    } else {
      // 获取用户信息
      // const hasGetUserInfo = store.getters.name
      const hasRoles = store.getters.roles && store.getters.roles.length > 0// 权限控制
      console.log('roles:',store.getters.roles)
      // if (hasGetUserInfo) {
      if (hasRoles) {
        console.log('执行了1')
        next()
      } else {
        console.log('执行了2')
        try {
          // get user info 重新获取用户信息
          // await store.dispatch('user/getInfo')
          // 权限控制
          console.log('tore.getters.roles:',store.getters.roles)
          const { roles } = await store.dispatch('user/getInfo')
          // 在角色权限基础上生成动态路由表
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          console.log('accessRoutes:',accessRoutes)
          router.options.routes = store.getters.permission_routes 
          // 动态添加可访问路由
          router.addRoutes(accessRoutes)
          // 在这动态添加最后的通配路由,确保先有动态路由、再有通配路由,解决动态路由刷新会跳转到404问题
          let lastRou = [{ path: '*', redirect: '/404' }]
          router.addRoutes(lastRou)
          console.log('输出的store:',store)
          next({...to, replace: true })
          
          // next()

        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(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 directly
      next()
    } 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 bar
  NProgress.done()
})

  • 36
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值