vue3项目中实现动态路由

完成效果

 
  1. 1.登录----根据用户登录获取当前用户的菜单
  2. 2.开始发送ajax 获取菜单
  3. 3.菜单解析为路由相关配置
  4. 4.添加到路由配置当中
  5. 5.动态路由实现完成

第一步:配置静态路由

 
//main.ts
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import "element-plus/theme-chalk/index.css";
//导入
import router from "./router/index";
//将路由关联到vue3 项目
createApp(App).use(router).mount("#app");
 
路由模块文件
index.ts
import { createRouter, createWebHistory } from "vue-router";

import routes from "./routes";

const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savePosiation) {
if (savePosiation) {
return savePosiation;
}
return { left: 0, top: 0 };
},
});

export default router;

//静态路由配置文件
//路由配置
//引入组件
import Index from "@/views/Index.vue";
import Login from "@/views/Login.vue";
import NotFound from "@/views/Not-found.vue";

export default [
{
path: "/",
component: Index,
name: "admin",
},
{
path: "/login",
component: Login,
},
{
path: "/not-found",
component: NotFound,
},
{
path: "/:pathMatch(.*)*", //vue2 * vue3 改为正则
redirect: "/not-found",
},
];

第二步实现登录和安全守卫

 
//守卫
let whiteList = ["/login", "/not-found"];
router.beforeEach((to, from) => {
//读取token
let token = localStorage.getItem("_token");

//未登录
if (!token) {
if (whiteList.indexOf(to.path) == -1) {
return { path: "/login" };
}
} else {
if (to.path == "/login") {
return { path: "/" };
}
}
});

第三步:发送请求获取用户动态菜单

 
1.获取用户菜单接口
//用户模块

import { get } from "../utils/request";

//获取用户菜单
export const getUserMenu = () => {
return get("/getRouters");
};
 
2.在守卫中发送请求获取menu
//守卫
let whiteList = ["/login", "/not-found"];
//定义菜单
let Menu: any = null;
router.beforeEach(async (to, from) => {
//读取token
let token = localStorage.getItem("_token");

//未登录
if (!token) {
if (whiteList.indexOf(to.path) == -1) {
return { path: "/login" };
}
} else {
if (to.path == "/login") {
return { path: "/" };
}
//能检测到登录完成
if (!Menu) {
//发送请求
let res = await getUserMenu();
console.log(res.data.data);
}
}
});

 
3.封装一个递归方法解析菜单
//解析菜单
function CompilerMenu(arr: Array<any>) {
if (!arr.length) {
return;
}
arr.forEach((item) => {
//定义对象
let rts = {
name: item.name,
path: item.path,
meta: item.meta,
component: item.component,
};
//如果存在子集进行递归解析
if (item.children && item.children.length) {
CompilerMenu(item.children);
}
console.log(rts);
});

 
4.针对解析的数据 进行组件懒加载
vite工具
import.meta.glob()
//使用vite懒加载
let Module = import.meta.glob("@/views/**/*.vue");
console.log("====================================");
console.log(Module);
console.log("====================================");

 
5.将item.component 解析为组件动态
//如果没有子集 证明为路由层
if (!item.children) {
//实现组件懒加载
let paths = loadComponent(item.component);
console.log(paths);
}

//懒加载组件
function loadComponent(url: string) {
let path = Module[`/src/views/${url}.vue`];
return path;
}
 
6.调用addRouter实现动态路由添加
//如果没有子集 证明为路由层
if (!item.children) {
//实现组件懒加载
let paths = loadComponent(item.component);
rts.component = paths;
console.log(rts);
//添加动态路由
router.addRoute("admin", rts);
}
});
 
  1. 7.检测动态路由添加
  2. //检测动态路由
  3. console.log(router.getRoutes(), router.hasRoute("Housepay"));

第四步测试动态路由

配置二级动态

 
<script setup lang="ts"></script>
<template>
admin
<router-link to="/housepay">商铺综合收费</router-link>
<router-link to="/temppay">临时收费</router-link>
<!-- 二级出口 -->
<RouterView></RouterView>
</template>

刷新导致动态路由匹配不到 直接 404

 
刷新 使用动态路径匹配的时候在路由中没有对应的路由 直接匹配到*路由 重定向到404
守卫添加以下代码
//手动添加404相关处理
router.addRoute({
path: "/not-found",
component: NotFound,
});
router.addRoute({
path: "/:pathMatch(.*)*", //vue2 * vue3 改为正则
redirect: "/not-found",
});
console.log(router.getRoutes());
//处理
return { path: to.path };
静态配置中404 *路由删除 采用手动配置。

第五步设置菜单数据缓存

 
//设置菜单数据缓存
localStorage.setItem("_menu", JSON.stringify(Menu));

组件中进行递归
<script setup lang="ts">
interface propType {
children: Array<any>;
}
defineProps<propType>();
</script>
<template>
<template v-for="(item, index) in children">
<template v-if="!item.children">
<el-menu-item index="1-3">{{ item.meta.title }}</el-menu-item>
</template>
<template v-else>
<!-- 当前级是否存在子集 -->
<el-sub-menu index="1-4">
<template #title>{{ item.meta.title }}</template>
//组件递归
<MenuItem :children="item.children"></MenuItem>
</el-sub-menu>
</template>
</template>
</template>

最后实现最终效果

  • 10
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态路由是指在运行时根据某些条件或数据来添加或修改路由。在Vue3,你可以使用Pinia来实现动态路由。具体的实现步骤如下: 1. 首先,在项目安装并配置Pinia。Pinia是一个Vue状态管理库,它可以帮助我们管理全局状态和实现动态路由。你可以通过npm或yarn安装Pinia,并在Vue应用程序的入口文件进行配置。 2. 创建一个包含需要动态添加的路由的数据源。你可以使用Pinia来定义一个数据仓库,包含一个数组,存储需要动态添加的路由对象。 3. 在需要添加动态路由的地方,使用Pinia的数据源来添加路由。你可以使用`router.addRoute`方法来添加路由,将数据仓库的路由对象传递给它。 4. 在路由守卫处理页面刷新时的跳转问题。当页面刷新后,动态添加的路由可能无法正常跳转,因此你需要在路由守卫使用`router.push`方法来跳转到正确的路由路径。这样即使会有错误提示,但不会影响使用。 综上所述,使用Pinia实现动态路由的基本步骤有:安装并配置Pinia、创建数据仓库、使用`router.addRoute`添加路由、在路由守卫使用`router.push`跳转页面。通过这些步骤,你可以实现Vue3动态路由功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue3动态路由](https://blog.csdn.net/m0_46978096/article/details/121532229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值