当前位置: 首页 > 知识库问答 >
问题:

前端 - vue-router3动态路由刷新出现白屏?

楚弘益
2023-05-17

最近在使用vue-admin-template开发后台管理系统,遇到动态路由刷新出现页面白屏问题

用户登录时通过角色获取角色路由并动态加载到router对象

  login({ commit }, userInfo) {
    const { username, password } = userInfo;
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password })
        .then(async (response) => {
          // 本地存储;
          sessionStorage.setItem("user", JSON.stringify(response.data));
          const { data, token } = response;
          commit("SET_TOKEN", token);
          setToken(token);

          // 获取角色;
          const datas = await getUserRole();
          if (datas.role === 2) {
            router.addRoutes(adminRouters);
            commit("SET_ROUTER", adminRouters);
          } else {
            commit("SET_ROUTER", userRouters);
            router.addRoutes(userRouters);
          }    
          resolve();
        })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });

在App.vue 中将保存于vuex中的路由信息刷新前存入到sessionStorage中,刷新后取出并重新加载路由;

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import store from "@/store/index";
import { resetRouter } from "@/router/index";
export default {
  name: "App",
  beforeCreate() {
    try {
      if (sessionStorage.getItem("store")) {
        this.$store.replaceState(
          Object.assign(
            {},
            this.$store.state,
            JSON.parse(sessionStorage.getItem("store"))
          )
        );
//重置路由
        resetRouter(store.getters.router);
        sessionStorage.removeItem("store");
      }
    } catch (error) {
      console.log(error);
    }
    //在页面刷新时将vuex里的信息保存到sessionStorage里
    window.addEventListener("beforeunload", () => {
      sessionStorage.setItem("store", JSON.stringify(this.$store.state));
    });
  },
};
</script>

重置路由方法

import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);

const createRouter = () =>
  new Router({
    // mode: 'history', // require service support
    scrollBehavior: () => ({ y: 0 }),
   // constantRoutes:静态路由数组
    routes: constantRoutes,
  });

export function resetRouter(ROUTES) {
  router = createRouter(); // reset router
  router.addRoutes(ROUTES);
}

全局路由守卫

import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import { getToken } from "@/utils/auth"; // get token from cookie
import getPageTitle from "@/utils/get-page-title";

NProgress.configure({ showSpinner: false }); // NProgress Configuration

const whiteList = ["/login"]; // no redirect whitelist

router.beforeEach(async (to, from, next) => {
  // start progress bar
  NProgress.start();

  // set page title
  document.title = getPageTitle(to.meta.title);

  // 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: "/documentInfo" });
      NProgress.done();
    } else {
      const hasGetUserInfo = store.getters.name;
      if (hasGetUserInfo) {
        next();
      } else {
        try {
          // get user info
          await store.dispatch("user/getInfo");
          next({ ...to, replace: true });
        } catch (error) {
          // remove token and go to login page to re-login
          console.log(error);
          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");
      NProgress.done();
    }
  }
});

router.afterEach(async (from, to) => {
  NProgress.done();
});

角色路由直接编写在JS文件中

// 路由形式
export const userRouters = [
  {
    path: "/document",
    component: Layout,
    name: "document",
    hidden: false,
    meta: { title: "档案资料", icon: "archives" },
    children: [
      {
        path: "/documentInfo",
        name: "documentInfos",
        component: () => import("@/views/document/index"),
        hidden: false,
        meta: { title: "个人档案" },
      },
      {
        path: "/documentInput",
        name: "documentInputs",
        component: () => import("@/views/document/admin/addorupdate"),
        meta: { title: "档案录入" },
      },
    ],
  },
 // 省略
  { path: "*", redirect: "/404", hidden: true },
];

出现问题正常登录能够进行路由跳转但是点击浏览器刷新出现页面白屏,请问该如何解决?
image.png

共有2个答案

弓智明
2023-05-17

你的重置路由那里改一下
const router = createRouter()

export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}

APP.vue中重置时,执行
resetRouter()
router.addRoutes(store.getters.router)

孙梓
2023-05-17

可以看看这个,希望可以帮助你解决问题:
https://blog.csdn.net/qq_40315210/article/details/129692160

 类似资料:
  • router配置 点击进去页面时 这样点击后页面会出现但是刷新或者跳转别的路由会报错 刷新报错: 跳转其他路由报错: 如何解决?

  • 目前是开发环境,history模式,有个index.vue的主页加了路由组件<RouterView/>,在路由导航守卫中向这个页面动态加了子路由,点击菜单的时候,跳转到了对应页面,但刷新后会打到404页面,后面发现是加了这个导致的“path: "/:catchAll(.*)",redirect: '/404',” 如果不加则正常,但是控制台会出现警告[Vue Router warn]: No ma

  • 本文向大家介绍详解vue路由篇(动态路由、路由嵌套),包括了详解vue路由篇(动态路由、路由嵌套)的使用技巧和注意事项,需要的朋友参考一下 什么是路由?网络原理中,路由指的是根据上一接口的数据包中的IP地址,查询路由表转发到另一个接口,它决定的是一个端到端的网络路径。 web中,路由的概念也是类似,根据URL来将请求分配到指定的一个'端'。(即根据网址找到能处理这个URL的程序或模块) 使用vue

  • 内置了一个组件,想每次打开都用一个新路由打开,但是显示不出来

  • vue实现动态按钮借助iview的Button,由于这些按钮是配置出来的,目前没有代码,还不清楚怎么写,所以麻烦大佬们了 如图 期望能在各个vue组件使用的,然后通过不同的点击来触发事件,希望大佬们,给个思路

  • 想通过v-router路由守卫和vuex实现一个动态路由,路由数据由后端返回,求一个demo参考下。