feat: 路由示例页,完善了普通路由和动态路由跳转,并且解决了标签页切换时路由参数丢失问题
This commit is contained in:
parent
103ab4802e
commit
2080e8fe55
@ -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
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user