前言
之前用vue+ant-design-vue写了一个动态路由的页面,更新看一下不能用了555~~~ 之前用的组件版本不知道了,回退也不知道哪个版本合适,就是用"vue": "^3.2.13" , "vue-router": "^4.0.3","vuex": "^4.0.0",ant-design-vue": "^3.2.5" 重新写一个吧。 本文章是看了其它杂七杂八的博客,自己排错后编写下,不容易啊
实现
- 首先在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: {
}
})
- 接着在App.vue编写
原因: 刷新时,动态路由需要重新挂载到路由实例, 但是在App.vue中调用init方法去初始化,并不能解决,因为App.vue属于路由的根,还未进入就被通配符拦截到404页面了, 我就在根上退出时将菜单保存在sessionStorage
created() {
if (sessionStorage.getItem("store")) {
this.$store.replaceState(
Object.assign(
{},
this.$store.state,
JSON.parse(sessionStorage.getItem("store"))
)
);
}
window.addEventListener("beforeunload", () => {
sessionStorage.removeItem("store");
sessionStorage.setItem("store", JSON.stringify(this.$store.state));
});
}
- 读取后端菜单文件进行处理下
根据实际修改 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}`),
});
if (!sessionStorage.getItem("store")) {
store.dispatch("menu_add", itemRouter);
}
}
if (itemRouter.children && itemRouter.children.length) {
routerPackag(itemRouter.children);
}
return true;
});
return accessedRouters;
}
}
)}
- 主要的来了,可以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',
component: () => import( '../views/ant_login.vue'),
meta: {
requireAuth: false,
},
},
{
path: '/',
name: 'base',
component: () => import( '../views/ant_base.vue'),
meta: {
requireAuth: true,
},
children: [
{
path: 'index',
name: 'home',
redirect: "/map",
component: () => import( '../views/ant_home.vue'),
}
]
},
{
name: "NotFont",
path: '/:pathMatch(.*)*',
component: () => import('../components/NotFont.vue'),
alias: '/404',
hideMenu: true
}
]
const router = createRouter({
history: createWebHashHistory(),
base: process.env.BASE_URL,
routes
})
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({
path: `${to.path}`
})
} else {
router.addRoute(router.options.routes[2])
next()
}
})
router.afterEach(() => {
});
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 })我就想知道你是咋成功的,哎,排的有好的但不实用,排到垃圾就跟不想说了,连使用的组件都没有就光把一段代码粘贴上去,累累累😫
期望
码友们有啥更简单的方式实现前端动态路由刷新后能正常显示刷新前页面欢迎评论分享
|