vue3動(dòng)態(tài)路由刷新后空白或者404問題的解決
前言
之前用vue+ant-design-vue寫了一個(gè)動(dòng)態(tài)路由的頁面,更新看一下不能用了555~~~
之前用的組件版本不知道了,回退也不知道哪個(gè)版本合適,就是用"vue": "^3.2.13" , "vue-router": "^4.0.3","vuex": "^4.0.0",ant-design-vue": "^3.2.5"重新寫一個(gè)吧。
本文章是看了其它雜七雜八的博客,自己排錯(cuò)后編寫下,不容易啊
實(shí)現(xiàn)
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)
},
// 登出時(shí)調(diào)用將菜單數(shù)據(jù)刪除
menu_delect({ commit }) {
commit('menuDelect')
}
},
modules: {
}
})2.接著在App.vue編寫
原因: 刷新時(shí),動(dòng)態(tài)路由需要重新掛載到路由實(shí)例, 但是在App.vue中調(diào)用init方法去初始化,并不能解決,因?yàn)锳pp.vue屬于路由的根,還未進(jìn)入就被通配符攔截到404頁面了, 我就在根上退出時(shí)將菜單保存在sessionStorage
// 創(chuàng)建完畢狀態(tài)
created() {
//在頁面加載時(shí)讀取sessionStorage里的狀態(tài)信息
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
}
//在頁面刷新時(shí)將vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
sessionStorage.removeItem("store");
sessionStorage.setItem("store", JSON.stringify(this.$store.state));
});
}
3.讀取后端菜單文件進(jìn)行處理下
根據(jù)實(shí)際修改
vueRouter4中移除了addRouters,所以只能通過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}`),
});
// 通過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.主要的來了,可以main或者router\index編寫(我是在router\index編寫的)
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模式
// 頁面刷新白屏問題
// mode取值說明:
// 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文件編寫
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)畫等
router.afterEach(() => {
//不接受next
});
export default router登出頁面需要清除緩存
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore()
function Logout() {
// 將vuex的菜單數(shù)據(jù)刪除
store.dispatch("menu_delect");
window.sessionStorage.clear()
}
)}
排錯(cuò)過程
心累不說看了那些博客了真是大海撈個(gè)針,博客太雜了,有的寫的next({ …to, replace: true })我就想知道你是咋成功的,哎,排的有好的但不實(shí)用,排到垃圾就跟不想說了,連使用的組件都沒有就光把一段代碼粘貼上去,累累累??
總結(jié)
到此這篇關(guān)于vue3動(dòng)態(tài)路由刷新后空白或者404問題解決的文章就介紹到這了,更多相關(guān)vue3刷新空白或404內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)頁面跳轉(zhuǎn)和參數(shù)傳遞的兩種方式
這篇文章主要介紹了vue頁面跳轉(zhuǎn)和參數(shù)傳遞的兩種方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
解決Vue使用bus總線時(shí),第一次路由跳轉(zhuǎn)時(shí)數(shù)據(jù)沒成功傳遞問題
這篇文章主要介紹了解決Vue使用bus總線時(shí),第一次路由跳轉(zhuǎn)時(shí)數(shù)據(jù)沒成功傳遞問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
vue+element項(xiàng)目中過濾輸入框特殊字符小結(jié)
這篇文章主要介紹了vue+element項(xiàng)目中過濾輸入框特殊字符小結(jié),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
vue router下的html5 history在iis服務(wù)器上的設(shè)置方法
這篇文章主要介紹了vue router下的html5 history在iis服務(wù)器上的設(shè)置方法,需要的朋友參考下吧2017-10-10
Vue中子組件調(diào)用父組件的3種方法實(shí)例
vue子組件調(diào)用父組件的方法其實(shí)不難,最近整理了一下,下面這篇文章主要給大家介紹了關(guān)于Vue中子組件調(diào)用父組件的3種方法,需要的朋友可以參考下2022-05-05
Vue Getters和mapGetters的原理及使用示例詳解
Vuex的核心概念包括state、mutations、actions、getters和modules,今天,我們要深入探討其中一個(gè)關(guān)鍵部分:getters,以及它的相關(guān)輔助函數(shù)mapGetters,感興趣的朋友跟隨小編一起看看吧2024-08-08
vue開發(fā)利器之unplugin-auto-import的使用
unplugin-auto-import 解決了vue3-hook、vue-router、useVue等多個(gè)插件的自動(dòng)導(dǎo)入,也支持自定義插件的自動(dòng)導(dǎo)入,下面這篇文章主要給大家介紹了關(guān)于vue開發(fā)利器之unplugin-auto-import使用的相關(guān)資料,需要的朋友可以參考下2023-02-02
詳細(xì)聊聊前端如何實(shí)現(xiàn)token無感刷新(refresh_token)
實(shí)現(xiàn)token無感刷新對(duì)于前端來說是一項(xiàng)非常常用的技術(shù),其本質(zhì)是為了優(yōu)化用戶體驗(yàn),下面這篇文章主要給大家介紹了關(guān)于前端如何實(shí)現(xiàn)token無感刷新(refresh_token)的相關(guān)資料,需要的朋友可以參考下2022-11-11
如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)詳析
埋點(diǎn)分析是網(wǎng)站分析的一種常用的數(shù)據(jù)采集方法,下面這篇文章主要給大家介紹了關(guān)于如何通過Vue自定義指令實(shí)現(xiàn)前端埋點(diǎn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07

