vue动态路由路径重复及刷新丢失页面问题的解决

1,368 阅读2分钟

本文主要介绍 vue 动态路由路径重复问题及刷新丢失页面问题的解决方案,记录生活记录bug。

问题一: 动态添加完路由,切换路由时,vue会警告路由名字重复。

原因: 动态路由添加时,调用 addRoutes(), 他只会帮我们注入路由,不会帮我们把前面的路由清掉,因此,就会重复添加了。

解决方案:

1.首先先定义一个创建路由实例的函数:

const createRouter = () =>
  new Router({
    routes: constantRouterMap,
  });
  1. 重置路由方法
export function resetRouter(noHeader = true) {
    // noHeader 这个是项目中的头部导航栏
  const newRouter = createRouter(); // 重新创建一个路由实例
  routers.matcher = newRouter.matcher; // 将新的路由实例的matcher属性赋给原来路由实例的matcher属性,即可实现原路由实例重置
  if (noHeader) {
    routers.addRoutes(headersRouter);
  }
}
  1. 计算完动态路由后,插入路由中前进行路由重置
resetRouter(false);
// routers 是页面实例化的路由
routers.addRoutes(_.cloneDeep(DynamicRoutes));

问题二: 添加完路由后进行页面刷新后,动态添加的路由会消失,路径找不到

解决方案: 在页面路由权限判断页(permission.js)用了路由router.beforeEach可以直接判断路由刷新,在进行一次页面路由初始化派发。

router.beforeEach((to, from, next) => {
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === '/login') {
      next({
        path: store.state.permission.rootRoute
      })
    } else {
      let isFirst = store.state.permission.isGetRoutes
      store.dispatch('permission/initPage').then(() => {
        if (!isFirst && to.path == '/home') {
          next({
            path: store.state.permission.rootRoute
          })
        } else {
          next()
        }
      }).catch(() => {
        next()
      })
      next()
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
    }
  }
})

问题三: 切换不同角色权限,之前动态添加的路由没有被清除,进入看到的还是上次进入的权限页面。

问题原因: 在vue 的 store 中没有清空,把 store 里的route 清空就好,

解决方案: 可以在退出登录设置,也可以在添加路由时清空,以下代码为 store 内 permission.js 添加动态路由前清空路由

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes;
    state.routes = constantRoutes.concat(routes);
  },
  RESET_ROUTES: (state, payLoad) => {
    state.addRoutes = [];
    state.routes = [];
  }
}; 
generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      // 关键代码 == 添加路由前将路由重置为空
      commit("RESET_ROUTES");
      // 设置登录的路由权限
      let accessedRoutes;
   
     if (roles === 4) {
        // 教师登录
       accessedRoutes = teacherRouter;
     }
     if (roles === 3) {
       // 学生登录
       accessedRoutes = studentRouter;
     }

     commit("SET_ROUTES", accessedRoutes);
     resolve(accessedRoutes);
   }); 

下面是收集一下相关功能代码

定义一个创建路由的函数

// 定义一个创建路由的函数
const createRouter = () =>
  new Router({
    mode: "hash",
    // mode: "history", // require service support
    base: process.env.BASE_URL, // 路由基准地址   这是历史模式使用的 为了防止后端路径冲突
    // scrollBehavior: () => ({ y: 0 }),
    // routes: constantRoutes, // constantRoutes静态路由映射
    // routes: [...constantRoutes, ...asyncRoutes], // 静态+动态 放在一起
    routes: [...constantRoutes], // 只有静态  放在一起   动态路由后面按根据用户权限控制添加动态路由
  });

重置路由实例的方法

export function resetRouter(noHeader = true) {
  const newRouter = createRouter(); // 重新创建一个路由实例
  routers.matcher = newRouter.matcher; // 将新的路由实例的matcher属性赋给原来路由实例的matcher属性,即可实现原路由实例重置
  if (noHeader) {
    routers.addRoutes(headersRouter);
  }
}

3.动态添加路由

resetRouter(false);
inRouter.addRoutes(_.cloneDeep(DynamicRoutes));