vue3動(dòng)態(tài)路由刷新后空白或者404問(wèn)題的解決
前言
之前用vue+ant-design-vue寫(xiě)了一個(gè)動(dòng)態(tài)路由的頁(yè)面,更新看一下不能用了555~~~
之前用的組件版本不知道了,回退也不知道哪個(gè)版本合適,就是用"vue": "^3.2.13" , "vue-router": "^4.0.3","vuex": "^4.0.0",ant-design-vue": "^3.2.5"重新寫(xiě)一個(gè)吧。
本文章是看了其它雜七雜八的博客,自己排錯(cuò)后編寫(xiě)下,不容易啊
實(shí)現(xiàn)
1.首先在store\index.js文件編寫(xiě)
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)
},
// 登出時(shí)調(diào)用將菜單數(shù)據(jù)刪除
menu_delect({ commit }) {
commit('menuDelect')
}
},
modules: {
}
})2.接著在App.vue編寫(xiě)
原因: 刷新時(shí),動(dòng)態(tài)路由需要重新掛載到路由實(shí)例, 但是在App.vue中調(diào)用init方法去初始化,并不能解決,因?yàn)锳pp.vue屬于路由的根,還未進(jìn)入就被通配符攔截到404頁(yè)面了, 我就在根上退出時(shí)將菜單保存在sessionStorage
// 創(chuàng)建完畢狀態(tài)
created() {
//在頁(yè)面加載時(shí)讀取sessionStorage里的狀態(tài)信息
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
}
//在頁(yè)面刷新時(shí)將vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
sessionStorage.removeItem("store");
sessionStorage.setItem("store", JSON.stringify(this.$store.state));
});
}
3.讀取后端菜單文件進(jìn)行處理下
根據(jù)實(shí)際修改
vueRouter4中移除了addRouters,所以只能通過(guò)addRouter進(jìn)行路由的動(dòng)態(tài)添加
import { useRouter } from "vue-router";
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore();
const router = useRouter();
// 路由數(shù)據(jù)重新封裝
function routerPackag(routers) {
let accessedRouters = routers.filter((itemRouter) => {
if (itemRouter.component != "Layout") {
//處理組件---重點(diǎn)
router.addRoute("base", {
path: `/${itemRouter.path}`,
name: itemRouter.name,
component: () => import(`@/${itemRouter.component}`),
});
// 通過(guò)sessionStorage排查菜單是否存儲(chǔ),避免刷新后重復(fù)添加
if (!sessionStorage.getItem("store")) {
store.dispatch("menu_add", itemRouter);
}
}
//存在子集
if (itemRouter.children && itemRouter.children.length) {
routerPackag(itemRouter.children);
}
return true;
});
return accessedRouters;
}
}
)}
4.主要的來(lái)了,可以main或者router\index編寫(xiě)(我是在router\index編寫(xiě)的)
1、刷新404:將匹配全部為定義路徑到404的路由從靜態(tài)路由表中去除,在動(dòng)態(tài)權(quán)限路由都添加了之后在添加。
2、刷新白屏:如果是在路由守衛(wèi)router.beforeEach中檢測(cè)并用router.addRoute添加的路由,則需要將動(dòng)態(tài)權(quán)限路由添加后的next()放行,改為next({ path: ${to.path} })觸發(fā)新導(dǎo)航。
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模式
// 頁(yè)面刷新白屏問(wèn)題
// mode取值說(shuō)明:
// histroy:URL就像正常的 url,示例:http://localhost:8080/home
// hash:默認(rèn)值,會(huì)多一個(gè)“#”,示例:http://localhost:8080/#/home
// abstract”:url不變示例:http://localhost:8080
// mode: 'history',
base: process.env.BASE_URL,
routes
})
// 下面全局前置路由守衛(wèi)可在main文件編寫(xiě)
const registerRouteFresh = ref(true) // 定義標(biāo)識(shí),記錄路由是否添加
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 => {
//
// 處理組件---重點(diǎn)
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()
}
})
// 全局后置鉤子-常用于結(jié)束動(dòng)畫(huà)等
router.afterEach(() => {
//不接受next
});
export default router登出頁(yè)面需要清除緩存
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore()
function Logout() {
// 將vuex的菜單數(shù)據(jù)刪除
store.dispatch("menu_delect");
window.sessionStorage.clear()
}
)}
排錯(cuò)過(guò)程
心累不說(shuō)看了那些博客了真是大海撈個(gè)針,博客太雜了,有的寫(xiě)的next({ …to, replace: true })我就想知道你是咋成功的,哎,排的有好的但不實(shí)用,排到垃圾就跟不想說(shuō)了,連使用的組件都沒(méi)有就光把一段代碼粘貼上去,累累累??
總結(jié)
到此這篇關(guān)于vue3動(dòng)態(tài)路由刷新后空白或者404問(wèn)題解決的文章就介紹到這了,更多相關(guān)vue3刷新空白或404內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue cli 3.x 項(xiàng)目部署到 github pages的方法
這篇文章主要介紹了vue cli 3.x 項(xiàng)目部署到 github pages的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-04-04
VueX學(xué)習(xí)之modules和namespacedVueX詳細(xì)教程
這篇文章主要為大家介紹了VueX學(xué)習(xí)之modules和namespacedVueX詳細(xì)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
vue3.0實(shí)現(xiàn)移動(dòng)端電子簽名組件
這篇文章主要為大家詳細(xì)介紹了vue3.0實(shí)現(xiàn)移動(dòng)端電子簽名組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
使用Vue和ECharts創(chuàng)建交互式圖表的代碼示例
在現(xiàn)代 Web 應(yīng)用中,數(shù)據(jù)可視化是一個(gè)重要的組成部分,它不僅能夠幫助用戶更好地理解復(fù)雜的數(shù)據(jù),還能提升用戶體驗(yàn),本文給大家使用Vue和ECharts創(chuàng)建交互式圖表的示例,需要的朋友可以參考下2024-11-11
Vue3.3?+?TS4構(gòu)建實(shí)現(xiàn)ElementPlus功能的組件庫(kù)示例
Vue.js?是目前最盛行的前端框架之一,而?TypeScript?則是一種靜態(tài)類(lèi)型言語(yǔ),它能夠讓開(kāi)發(fā)人員在編寫(xiě)代碼時(shí)愈加平安和高效,本文將引見(jiàn)如何運(yùn)用?Vue.js?3.3?和?TypeScript?4?構(gòu)建一個(gè)自主打造媲美?ElementPlus?的組件庫(kù)2023-10-10
SpringBoot+Vue前后端分離,使用SpringSecurity完美處理權(quán)限問(wèn)題的解決方法
這篇文章主要介紹了SpringBoot+Vue前后端分離,使用SpringSecurity完美處理權(quán)限問(wèn)題,需要的朋友可以參考下2018-01-01
一文詳細(xì)了解Vue?3.0中的onMounted和onUnmounted鉤子函數(shù)
Vue3.0引入了新的組件生命周期鉤子函數(shù)onMounted和onUnmounted,分別用于組件掛載后和卸載前的操作,這些鉤子函數(shù)為開(kāi)發(fā)者提供了更多靈活性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10
Element Carousel 走馬燈的具體實(shí)現(xiàn)
這篇文章主要介紹了Element Carousel 走馬燈的具體實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

