feat: 路由示例页,完善了普通路由和动态路由跳转,并且解决了标签页切换时路由参数丢失问题

This commit is contained in:
WANGFan 2025-05-18 17:40:23 +08:00
parent 103ab4802e
commit 2080e8fe55
10 changed files with 73 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import pinia from "@/store/index"; import pinia from "@/store/index";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useRoutesConfigStore } from "@/store/modules/route-config"; import { useRoutesConfigStore } from "@/store/modules/route-config";
/** /**
* hooks * hooks
* @returns * @returns
@ -17,6 +18,17 @@ export const useRoutingMethod = () => {
return routeList.value.find((item: Menu.MenuOptions) => item.name == key); return routeList.value.find((item: Menu.MenuOptions) => item.name == key);
}; };
/**
*
* @param {string} key name
* @returns true存在 false不存在
*/
const hasRoute = (key: string) => {
const routerStore = useRoutesConfigStore(pinia);
const { routeList } = storeToRefs(routerStore);
return routeList.value.some((item: Menu.MenuOptions) => item.name == key);
};
/** /**
* tabs路由中查找路由 * tabs路由中查找路由
* @param {string} key name * @param {string} key name
@ -39,9 +51,20 @@ export const useRoutingMethod = () => {
} }
}; };
/**
* path必然带有"/:"/user/:id
* @param {string} path path
* @returns
*/
const isDynamicRoute = (path: string) => {
return path.includes("/:");
};
return { return {
findLinearArray, findLinearArray,
findTagsList, findTagsList,
openExternalLinks openExternalLinks,
isDynamicRoute,
hasRoute
}; };
}; };

View File

@ -112,7 +112,7 @@ const tabsChange = (e: Boolean) => {
tabsList.value = []; tabsList.value = [];
cacheRoutes.value = []; cacheRoutes.value = [];
} else { } else {
currentlyRoute(route.name as string); currentlyRoute(route);
} }
}; };

View File

@ -58,15 +58,23 @@ const router = useRouter();
const routerStore = useRoutesConfigStore(); const routerStore = useRoutesConfigStore();
const { tabsList, currentRoute } = storeToRefs(routerStore); const { tabsList, currentRoute } = storeToRefs(routerStore);
//
const routerPush = (route: any) => {
const { isDynamicRoute } = useRoutingMethod();
//
if (isDynamicRoute(route.path)) {
router.push({ name: route.name, params: route.params });
} else {
router.push({ path: route.path, query: route.query });
}
};
// //
const onTabs = (key: string) => { const onTabs = (key: string) => {
const { findTagsList } = useRoutingMethod(); const { findTagsList } = useRoutingMethod();
const find = findTagsList(key); const find = findTagsList(key);
console.log("点击", key, find); if (find == undefined) return;
routerPush(find);
if (find != undefined) {
router.push(find.path);
}
}; };
// //
@ -75,7 +83,7 @@ const onDelete = (key: string) => {
routerStore.removeRouteName(key); routerStore.removeRouteName(key);
if (tabsList.value.length == 0) return; if (tabsList.value.length == 0) return;
if (currentRoute.value.name != key) return; if (currentRoute.value.name != key) return;
router.push(tabsList.value.at(-1).path); routerPush(tabsList.value.at(-1));
}; };
// //
@ -141,7 +149,7 @@ const closeOther = (type: string) => {
routerStore.removeRouteNames(rightNames); routerStore.removeRouteNames(rightNames);
// //
if (tabsList.value.length != 0 && !currentRoute.value.meta.affix && type == "all") { if (tabsList.value.length != 0 && !currentRoute.value.meta.affix && type == "all") {
router.push(tabsList.value.at(-1).path); routerPush(tabsList.value.at(-1));
} }
}; };
</script> </script>

View File

@ -763,7 +763,7 @@ export const systemMenu = [
parentId: "0", parentId: "0",
path: "/functions", path: "/functions",
name: "functions", name: "functions",
redirect: "/functions", redirect: "/functions/routing-operation",
meta: { meta: {
title: "functions", title: "functions",
hide: false, hide: false,

View File

@ -37,7 +37,6 @@ const router = createRouter({
* addRoute动态添加的路由失效 * addRoute动态添加的路由失效
*/ */
router.beforeEach(async (to: any, _: any, next: any) => { router.beforeEach(async (to: any, _: any, next: any) => {
console.log("去", to);
NProgress.start(); // 开启进度条 NProgress.start(); // 开启进度条
const store = useUserInfoStore(pinia); const store = useUserInfoStore(pinia);
const { token, account } = storeToRefs(store); const { token, account } = storeToRefs(store);
@ -53,7 +52,7 @@ router.beforeEach(async (to: any, _: any, next: any) => {
// 3、去登录页有token直接重定向到home页 // 3、去登录页有token直接重定向到home页
next("/home"); next("/home");
// 项目内的跳转,处理跳转路由高亮 // 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string); currentlyRoute(to);
} else { } else {
// 4、去非登录页有token用户信息是否存在有则放行否则重新获取路由信息、初始化路由 // 4、去非登录页有token用户信息是否存在有则放行否则重新获取路由信息、初始化路由
const routeStore = useRoutesConfigStore(pinia); const routeStore = useRoutesConfigStore(pinia);
@ -65,7 +64,13 @@ router.beforeEach(async (to: any, _: any, next: any) => {
await store.setAccount(); await store.setAccount();
// 获取路由信息 // 获取路由信息
await routeStore.initSetRouter(); await routeStore.initSetRouter();
next({ path: to.path, query: to.query, params: to.params }); // 判断是否是动态路由
const { isDynamicRoute } = useRoutingMethod();
if (isDynamicRoute(to.path)) {
next({ name: to.name, params: to.params });
} else {
next({ path: to.path, query: to.query });
}
} else { } else {
// 获取外链路由的处理函数 // 获取外链路由的处理函数
// 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链 // 所有的路由正常放行,只不过额外判断是否是外链,如果是,则打开新窗口跳转外链
@ -76,7 +81,7 @@ router.beforeEach(async (to: any, _: any, next: any) => {
// 动态路由添加过走这里,直接放行 // 动态路由添加过走这里,直接放行
next(); next();
// 项目内的跳转,处理跳转路由高亮 // 项目内的跳转,处理跳转路由高亮
currentlyRoute(to.name as string); currentlyRoute(to);
} }
} }
}); });

View File

@ -19,9 +19,10 @@ export function linearArray(tree: any) {
* tabs栏数据 * tabs栏数据
* tabs标签栏数据 * tabs标签栏数据
* menu和tabs以及手动刷新浏览器等功能只需要跳转即可 * menu和tabs以及手动刷新浏览器等功能只需要跳转即可
* @param {object} name * @param {any} current
*/ */
export const currentlyRoute = (name: string) => { export const currentlyRoute = (current: any) => {
const route = deepClone(current);
const themeStore = useThemeConfig(); const themeStore = useThemeConfig();
const { isTabs } = storeToRefs(themeStore); const { isTabs } = storeToRefs(themeStore);
const store = useRoutesConfigStore(pinia); const store = useRoutesConfigStore(pinia);
@ -30,22 +31,23 @@ export const currentlyRoute = (name: string) => {
if (tabsList.value.length == 0 && routeList.value.length != 0) { if (tabsList.value.length == 0 && routeList.value.length != 0) {
store.setTabs(routeList.value[0]); store.setTabs(routeList.value[0]);
} }
// 跳转路由是有权限的,缓存跳转路由
const { findLinearArray } = useRoutingMethod(); // 跳转路由是有权限的,从有权限路由中匹配
const find = findLinearArray(name); const { hasRoute } = useRoutingMethod();
if (find === undefined) return; // 未找到,说明当前跳转路由无权限
if (!hasRoute(route.name)) return;
// 存入当前路由-高亮 // 存入当前路由-高亮
store.setCurrentRoute(find); store.setCurrentRoute(route);
// 如果是外链路由则不做后续任何缓存操作,条件: 有外链 && 非内嵌 // 如果是外链路由则不做后续任何缓存操作,条件: 有外链 && 非内嵌
if (find.meta.link && !find.meta.iframe) return; if (route.meta.link && !route.meta.iframe) return;
console.log("跳转存入tabs", tabsList.value, find);
// 存入tabs栏数据条件开启tabs // 存入tabs栏数据条件开启tabs
if (isTabs.value) store.setTabs(find); if (isTabs.value) store.setTabs(route);
// 不缓存路由 || 不渲染tabs ,符合任意条件则不缓存路由 // 不缓存路由 || 不渲染tabs ,符合任意条件则不缓存路由
if (!find.meta.keepAlive || !isTabs.value) return; if (!route.meta.keepAlive || !isTabs.value) return;
store.setRouteNames(find.name); // 缓存路由name store.setRouteNames(route.name); // 缓存路由name
}; };
/** /**

View File

@ -36,9 +36,11 @@ export const routesConfigStore = () => {
* @param {object} data tabs路由 * @param {object} data tabs路由
*/ */
function setTabs(data: Menu.MenuOptions) { function setTabs(data: Menu.MenuOptions) {
// 当前路由在tags中是否存在不存在则缓存 // 当前路由在tags中是否存在
let isExist = tabsList.value.some((item: Menu.MenuOptions) => item.name === data.name); let index = tabsList.value.findIndex((item: Menu.MenuOptions) => item.name === data.name);
if (isExist) return; // 如果存在,新路由替换旧路由,因为路由存在并不代表本次跳转的参数一致
if (index != -1) return tabsList.value.splice(index, 1, data);
// 不存在,直接缓存
tabsList.value.push(data); tabsList.value.push(data);
} }
/** /**
@ -46,7 +48,7 @@ export const routesConfigStore = () => {
* @param {object} data * @param {object} data
*/ */
function setCurrentRoute(data: Menu.MenuOptions) { function setCurrentRoute(data: Menu.MenuOptions) {
if (currentRoute.value.name && data.name === currentRoute.value.name) return; // 名称一样不代表参数相同,这不用做已存在匹配,直接存储当前路由
currentRoute.value = data; currentRoute.value = data;
} }
/** /**

View File

@ -62,8 +62,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
defineOptions({ name: "routing-operation" });
const router = useRouter(); const router = useRouter();
// //
const connom = ref({ const connom = ref({
path: "/test-common-route", path: "/test-common-route",

View File

@ -12,6 +12,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
defineOptions({ name: "test-common-route" });
const route = useRoute(); const route = useRoute();
</script> </script>

View File

@ -12,6 +12,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
defineOptions({ name: "test-dynamic-route" });
const route = useRoute(); const route = useRoute();
</script> </script>