vue3动态路由刷新后空白或者404问题的解决
作者:梧桐凰 发布时间:2023-07-02 16:58:39
前言
之前用vue+ant-design-vue写了一个动态路由的页面,更新看一下不能用了555~~~
之前用的组件版本不知道了,回退也不知道哪个版本合适,就是用"vue": "^3.2.13" , "vue-router": "^4.0.3","vuex": "^4.0.0",ant-design-vue": "^3.2.5"重新写一个吧。
本文章是看了其它杂七杂八的博客,自己排错后编写下,不容易啊
实现
1.首先在store\index.js文件编写
import { createStore } from 'vuex'
export default createStore({
state: {
menu_lists: [] //菜单
},
getters: {
account(state) {
return state.menu_lists // 读取菜单列表
}
},
mutations: {
// 增加菜单
menuAdd(state, n) {
if (state.menu_lists.length == 0) {
state.menu_lists.push(n)
} else {
if (state.menu_lists.some(menu => menu.name != n.name)) {
state.menu_lists.push(n)
}
}
},
// 清空菜单
menuDelect(state) {
state.menu_lists.length = 0
}
},
actions: {
menu_add({ commit }, data) {
commit('menuAdd', data)
},
// 登出时调用将菜单数据删除
menu_delect({ commit }) {
commit('menuDelect')
}
},
modules: {
}
})
2.接着在App.vue编写
原因: 刷新时,动态路由需要重新挂载到路由实例, 但是在App.vue中调用init方法去初始化,并不能解决,因为App.vue属于路由的根,还未进入就被通配符拦截到404页面了, 我就在根上退出时将菜单保存在sessionStorage
// 创建完毕状态
created() {
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
sessionStorage.removeItem("store");
sessionStorage.setItem("store", JSON.stringify(this.$store.state));
});
}
3.读取后端菜单文件进行处理下
根据实际修改
vueRouter4中移除了addRouters,所以只能通过addRouter进行路由的动态添加
import { useRouter } from "vue-router";
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore();
const router = useRouter();
// 路由数据重新封装
function routerPackag(routers) {
let accessedRouters = routers.filter((itemRouter) => {
if (itemRouter.component != "Layout") {
//处理组件---重点
router.addRoute("base", {
path: `/${itemRouter.path}`,
name: itemRouter.name,
component: () => import(`@/${itemRouter.component}`),
});
// 通过sessionStorage排查菜单是否存储,避免刷新后重复添加
if (!sessionStorage.getItem("store")) {
store.dispatch("menu_add", itemRouter);
}
}
//存在子集
if (itemRouter.children && itemRouter.children.length) {
routerPackag(itemRouter.children);
}
return true;
});
return accessedRouters;
}
}
)}
4.主要的来了,可以main或者router\index编写(我是在router\index编写的)
1、刷新404:将匹配全部为定义路径到404的路由从静态路由表中去除,在动态权限路由都添加了之后在添加。
2、刷新白屏:如果是在路由守卫router.beforeEach中检测并用router.addRoute添加的路由,则需要将动态权限路由添加后的next()放行,改为next({ path: ${to.path} })触发新导航。
import { createRouter, createWebHashHistory } from 'vue-router'
import store from "../store";
import { ref } from 'vue'
const routes = [
{
path: '/login',
name: 'login',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import( /* webpackChunkName: "Login" */ '../views/ant_login.vue'),
meta: {
requireAuth: false,
},
},
{
path: '/',
name: 'base',
component: () => import( /* webpackChunkName: "Login" */ '../views/ant_base.vue'),
meta: {
requireAuth: true,
},
children: [
{
path: 'index',
name: 'home',
redirect: "/map",
component: () => import( /* webpackChunkName: "Login" */ '../views/ant_home.vue'),
}
]
},
{
name: "NotFont",
path: '/:pathMatch(.*)*',
component: () => import('../components/NotFont.vue'),
alias: '/404', // 别名
hideMenu: true
}
]
const router = createRouter({
history: createWebHashHistory(), //createWebHashHistory是hash模式
// 页面刷新白屏问题
// mode取值说明:
// histroy:URL就像正常的 url,示例:http://localhost:8080/home
// hash:默认值,会多一个“#”,示例:http://localhost:8080/#/home
// abstract”:url不变示例:http://localhost:8080
// mode: 'history',
base: process.env.BASE_URL,
routes
})
// 下面全局前置路由守卫可在main文件编写
const registerRouteFresh = ref(true) // 定义标识,记录路由是否添加
router.beforeEach(async (to, from, next) => {
if (registerRouteFresh.value && store.state.menu_lists.length > 0) {
router.removeRoute("NotFont")
await store.state.menu_lists.forEach(e => {
//
// 处理组件---重点
router.addRoute("base", {
path: `/${e.path}`,
name: e.name,
component: () => import(`@/${e.component}`),
});
})
registerRouteFresh.value = false
// next({ ...to, replace: true })
next({
path: `${to.path}`
})
} else {
router.addRoute(router.options.routes[2])
next()
}
})
// 全局后置钩子-常用于结束动画等
router.afterEach(() => {
//不接受next
});
export default router
登出页面需要清除缓存
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore()
function Logout() {
// 将vuex的菜单数据删除
store.dispatch("menu_delect");
window.sessionStorage.clear()
}
)}
排错过程
心累不说看了那些博客了真是大海捞个针,博客太杂了,有的写的next({ …to, replace: true })我就想知道你是咋成功的,哎,排的有好的但不实用,排到垃圾就跟不想说了,连使用的组件都没有就光把一段代码粘贴上去,累累累😫
来源:https://blog.csdn.net/weixin_43613890/article/details/125320428


猜你喜欢
- 本文实例讲述了Python3使用turtle绘制超立方体图形。分享给大家供大家参考,具体如下:利用Python3中turtle的绘制超立方体
- 本文主要讲python支持zookeeper的接口库安装和使用。zk的python接口库有zkpython,还有kazoo,下面是zkpyt
- mysql最常用的索引结构是btree(O(log(n))),但是总有一些情况下我们为了更好的性能希望能使用别的类型的索引。hash就是其中
- 前言:列表框控件显示多行文本,用户可以选中一行或者多行。所有的文本只能使用一种字体,不能混合使用多种字体。1 属性常用的参数列表如下:1.1
- 最近在写的一个django小项目需要实现用户上传图片的功能,使用到了七牛云存储,特此记录下来。这里我使用的七牛python SDK 版本是7
- 本文实例讲述了Django中使用group_by的方法。分享给大家供大家参考。具体分析如下:在Django中怎样使用group_by语句呢?
- 前言内存映射通常可以提高I/O的性能,因为使用内存映射时,不需要对每个访问都建立一个单独的系统调用,也不需要在缓冲区之间复制数据,内核和用户
- Create a Simple API Using Django REST Framework in PythonWHAT IS AN AP
- 投资有风险,选择需谨慎。 股票交易数据分析可直观股市走向,对于如何把握股票行情,快速解读股票交易数据有不可替代的作用!1 数据预处
- 应用场景在嵌入式开发中,常常需要将一个binary文件分割成多个文件,或者将一个binary的某块区域抓成一个单独文件。本篇blog以pyt
- 目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件)、
- 在并发编程中,多个Goroutine访问同一块内存资源时可能会出现竞态条件,我们需要在临界区中使用适当的同步操作来以避免竞态条件。Go 语言
- mapmap(funcname, list)python的map 函数使得函数能直接以list的每个元素作为参数传递到funcname中,
- 问题:在Jupyter Notebook中使用args传递参数时出现错误:原始代码:args = parser.parse_args()us
- 我们以一个例子展开这个题目问题:python类对象A,先实例化一个A对象的实例b,接着给A对象添加一个类共享变量xxx,再实例化一个c,请问
- mysql replace实例说明:UPDATE tb1 SET f1=REPLACE(f1, 'abc', 'de
- 使用BootstrapValidator进行注册校验和登录错误提示,具体内容如下1、介绍在AdminEAP框架中,使用了BootstrapV
- 一、环境pip install opencv-pythonpython3.9pycharm2020人狠话不多,直接上代码,注释在代码里面,不
- Python字符串拼接的6种方法:1.加号第一种,有编程经验的人,估计都知道很多语言里面是用加号连接两个字符串,Python里面也是如此直接
- 这个收藏本站、设为首页代码相信每个网站都会用到,这么常用的代码,网络上流行的一般是很多年前的代码版本,只有兼容IE,对其它浏览器没有考虑,下