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