在做后台管理系统的过程中,遇到一个问题,404 页面会不合时宜地出现:

用户直接输入 url 访问,出现 404 页面

这是一个比较糟糕的情况,用户点开一个链接,进去就是 404 ,用户体验很不好。因此对这个问题进行了分析解决。

其中的关键点是,这是一个后台管理系统,路由是前端根据当前用户角色动态生成的,需要控制使其不能访问其没有权限访问的页面

期望解决方案:

  • 如果用户没有登录过,跳转至登录页面,登录后再跳至指定页面
  • 用户已登录,则根据其权限判断是到指定页面还是首页

分析思路:

404 是当用户访问路由表里没有设置的路径时出现的页面,所以,在路由导航钩子函数里判断目的路径进行重定向即可

解决方法:

1、针对用户打开新的浏览器窗口输入的情况(即未登录),跳转至登录页

这里根据当前是否保存有动态计算的路由数组进行判断,也可以根据有无 token 判断

router.beforeEach(async (to, from, next) => {
  if (from.path === '/' && !util.cookies.get('savedRouteList')) {
    next({
      name: 'login',
      query: {
        redirect: to.fullPath
      }
    })
  }
}

2、针对用户已登录系统,浏览器新开 Tab 标签输入 url 的情况

这里根据目标路由是否存在于路由表中进行判断,即只需判断目的路由是否 404 页面,已存在的路由会直接访问,无需操作

router.beforeEach(async (to, from, next) => {
  // 这里不用 from.path 进行判断
  // 因为浏览器先访问目标页面,如果其不存在,再转到 404 页面,则 from.path 变成了目标页面的路径
  if (from.name === null && to.name === 'notFound') {
      this.$message.warning('您没有权限访问当前页面,已为您重定向至首页')
      const firstAccessedRoute = store.state.d2admin.user.accessedRouters[0].children[0].name
      // 访问当前权限路由中第一个路由,如果为空则回到登录页
      next ({
        name: firstAccessedRoute || 'login'
      })
    }
}

完整代码:

router.beforeEach(async (to, from, next) => {
  if (from.path === '/' && !util.cookies.get('savedRouteList')) {
      next ({
        name: 'login',
        query: {
            redirect: to.fullPath
        }
      })
    }
    if (from.name === null && to.name === 'notFound') {
      this.$message.warning('您没有权限访问当前页面,已为您重定向至首页')
      const firstAccessedRoute = store.state.d2admin.user.accessedRouters[0].children[0].name
      next ({
        name: firstAccessedRoute || 'login'
      })
    }
}

将臣
2.3k 声望107 粉丝

学习、分享技术