1.添加组件vue-router

yarn add vue-router

2.动态路由添加

创建文件/router/index.ts

import { createRouter, createWebHashHistory, RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
import { Session } from '@/utils/storage';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { HOME_NAME,LOGIN_PATH } from '@/utils/constant';
import { useMenuStore } from '@/stores/menu';
import staticRoutes from './static';

const router = createRouter({
  history: createWebHashHistory(),
  routes: [...staticRoutes],
});

async function canUserAccess(_to:RouteLocationNormalized){
	const token = Session.get('token');
	return !!token;
}


/**
 * 动态添加路由
 * @param {*} parentName
 * @param {*} menus
 */
const addRoutes = (parentName: string,menus: MenuInfo[] = [])=> {
	const parentRouter: RouteRecordRaw = {path: '',name: parentName,children:[]};

	menu2Routes( parentRouter, menus);
	const pr = router.getRoutes().find(v=>v.name== parentName);
	if(pr){
		pr.children = parentRouter.children;
		router.addRoute(pr);
	}
}

/**
 * 菜单转路由列表
 * @param {*} parentRouter
 * @param {*} menus
 */
const menu2Routes = (parentRouter: RouteRecordRaw, menus: MenuInfo[] = [])=>{
	menus.forEach((info)=>{
		const newRouter = {
			path: info.path,
			name: info.name,
			children:[],
			meta:{title: info.title}
		};
		if(info.children && info.children.length==0){
			newRouter.component =()=>import(`/src/views/modules${ info.path }/index.vue`);
		} 

		parentRouter?.children?.push( newRouter );
		
		if(info.children && info.children.length>0){
			menu2Routes(newRouter, info.children);
		}
	});
}

/**
 * 扩展router,添加刷新路由方法
 */
router.refreshRouters=()=>{
	//解决刷新界面路由重置问题
	const useMenu = useMenuStore();  
    //将菜单路由挂载到HOME_NAME静态路由下
	addRoutes(HOME_NAME, useMenu.menus);
	return router;
}

router.beforeEach(async (to, _from) => {
	NProgress.configure({showSpinner: false});
	NProgress.start();
	const canAccess = await canUserAccess(to);
	if (!canAccess && to.path !=LOGIN_PATH) return LOGIN_PATH;
})

router.afterEach((_to, _from, _failure) => {
	NProgress.done()

})


// 添加异常处理
const originalPush = router.push
router.push = (to) => {
  try {
    return originalPush(to)
	
  } catch (error) {
    window.console.log(`%c${ error }`, 'color:red')
    return originalPush({ name: '404' })
  }
}

// 导出路由
export default router;

静态路由文件/router/static.ts

import { RouteRecordRaw } from 'vue-router';
import { HOME_NAME,HOME_PATH, LOGIN_NAME,LOGIN_PATH,MENU_DEFAULT_ACTIVE } from '@/utils/constant';

const staticRoutes: Array<RouteRecordRaw> = [
	{
        path: '/',
        redirect: MENU_DEFAULT_ACTIVE,
    },
	{
		path: HOME_PATH,
		name: HOME_NAME,
		component: () => import('@/views/home/index.vue'),
		meta: {
			title: '主页',
		},
		children:[],
	},
	{
		path: LOGIN_PATH,
		name: LOGIN_NAME,
		component: () => import('@/views/login/index.vue'),
		meta: {
			title: '登录',
		},
	},
	
	{
		path: '/:path(.*)*',
		name: 'notFound',
		component: () => import('@/views/error/404.vue'),
		meta: {
			title: '找不到此页面',
		},
	},
	{
		path: '/401',
		name: 'noPermission',
		component: () => import('@/views/error/401.vue'),
		meta: {
			title: '没有权限',
		},
	},
];

export default staticRoutes;

3.使用动态路由

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus';
import router from '@/router'
import i18n from '@/locale'

import 'element-plus/dist/index.css';
import './style.css'

const app = createApp(App)
//添加动态路由使用
//refreshRouters --解决刷新界面路由重置问题
app.use(router.refreshRouters());
app.use(i18n.loadDefault());
app.use(ElementPlus);
app.mount('#app')

4.添加面包屑

mkdir -p src\\views\\home\\components\\headbar\\components\\crumb

crumb目录下创建文件index.ts

<template>
  <el-breadcrumb separator="/" class="crumb-container flex">
    <transition-group name="right-in-out">
      <el-breadcrumb-item
        v-for="item in crumbs"
        :key="item.name">
        {{ item.meta?.title }}
      </el-breadcrumb-item>
    </transition-group>
  </el-breadcrumb>
</template>

<script setup lang="ts">
import {ref,watchEffect} from "vue"
import { useRoute, RouteRecordRaw } from 'vue-router'

const crumbs = ref<RouteRecordRaw[]>([]);
const route = useRoute();

const crumbHandle = ()=>{
	crumbs.value = []
    //读取路由信息
	route.matched.forEach((item) => {
		crumbs.value.push(item);
	});
	//因为是挂载主页路由下,所以去掉根节点
	crumbs.value.shift();
}


watchEffect(() => {
  crumbHandle()
})

</script>

<style lang="scss" scoped>

:deep(.el-breadcrumb__inner) {
  font-weight:bolder;
}

</style>

5.效果

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐