vue3 面包屑三级or多级路由配置
面包屑组件可以清晰的显示当前页面的路径,快速返回之前的任意页面。那么三级或者多级路由应该怎样配置,这里以自己写的代码为例,先看看实现效果。
·
目录
面包屑组件可以清晰的显示当前页面的路径,快速返回之前的任意页面。
那么三级或者多级路由应该怎样配置,这里以自己写的代码为例,先看看实现效果
实现效果
这里是三级路由的配置,面包屑展示的路径是在router里面配置的。
看起来是“三级”,其实是多级嵌套起来的,
借助了两个layout才展示出“三级”甚至“四级”的路由,如图:
面包屑上黑色的路径是能点击跳转的。
首先是路由的配置如下
router/index.js
export const asyncRoutes = [
//后台管理系统
{
path: '/background',
component: Layout,//第一个layout,带main
name: 'background-manage',
meta: {
title: '后台管理',
icon: 'fa fa-tasks'
},
redirect: 'noRedirect',
children: [
//后台管理系统--用户管理————“二级路由”
{
path: 'backgroundUser',
name: 'backgroundUser-manage',
component: LayoutBlank,
meta: {
title: '用户管理',
icon: 'fa fa-users'
},
//这里写用户管理里面的子页面
children: [
//第一个是用户管理的页面
{
path: '',
name: 'backgroundUser',//如果页面代码里面跳转路由是通过name,那么name一定要唯一
component: () => import('@/views/background/backgroundUser.vue'),
hidden: true//这个一定要写,要不然左侧导航栏里面就会出现很多级
},
//用户管理的子页面,比如新增用户之类的页面
{
path: 'backgroundUserCreate/:id',
name: 'backgroundUser',
component: () => import('@/views/background/backgroundUserCreate.vue'),
meta: {
title: '新建用户',
icon: 'fa fa-users',
},
props: true,
hidden: true
}
]
},
//后台管理系统--项目管理————“三级路由”或者更多
{
path: 'project',
component: LayoutBlank,//第二个layout 不带main,下文解释
meta: {
title: '项目管理',
icon: 'fa fa-list'
},
children: [
//第一个页面时项目管理的页面,和上面的用户管理一样
{
path: '',
name: 'project',
component: () => import('@/views/background/project.vue'),
hidden: true
},
{
path: 'projectManage',
component: LayoutBlank,//一定是这个
meta: { title: '管理项目成员', icon: 'fa fa-users'}
props: true,
hidden: true,
children: [
//这里是“管理项目成员”的页面
{
path: '',
name: 'project-manage',
component: () => import('@/views/background/projectUpdate.vue'),
hidden: true,
props: true
},
//管理项目成员的子页面——成员详情
{
path: 'projectMemberInfo',
name: 'projectMember-info',
component: () => import('@/views/background/projectMemberInfo.vue'),
meta: { title: '成员详情', icon: 'fa fa-users'},
hidden: true
}
]
}
]
},
// 日志管理
{
path: 'project-op-log',
component: LayoutBlank,
meta: {
title: '日志管理',
icon: 'fa fa-file-medical-alt'
},
children: [
{
path: '',
name: 'projectOpLog',
component: () => import('@/views/background/userOpLogs.vue'),
hidden: true
}
]
}
]
},
//个人设置
{
path: '/personalSetting',
component: Layout,
children: [
{
path: 'userSetting',
component: () => import('@/views/user/index.vue'),
name: 'userSetting',
accessControl: true,
meta: { title: '个人设置', icon: 'fa fa-user-circle' }
}
]
},
// 404 page must be placed at the end !!!
// using pathMatch install of "*" in vue-router 4.0
{ path: '/:pathMatch(.*)', redirect: '/404', hidden: true }
]
两个layout页面,主layout的HTML是这样的:
Layout.vue
<template>
<div :class="classObj" class="layout-wrapper">
<!--left side-->
<Sidebar class="sidebar-container" />
<!--right container-->
<div class="main-container">
<Navbar />
<TagsView />
<AppMain />
</div>
</div>
</template>
第二个layout是空白的只是为了占位:
LayoutBlank.vue
<template>
<div class="layout-wrapper">
<!--right container-->
<div>
<router-view />
</div>
</div>
</template>
<!--原理vue2.0-->
<script>
/*可以设置默认的名字*/
export default {
name: 'LayoutBlank'
}
</script>
以上两个layout在路由里面使用时需要先import
除了以上,引用面包屑还需要配置路由的引用方式,在layout文件夹下面的components文件夹里面新建一个文件 Breadcrumb.vue,在这里引用面包屑组件,具体的代码可以参考这里:
Breadcrumb.vue
<template>
<el-breadcrumb class="app-breadcrumb" separator="/">
<!--has transition Judging by settings.mainNeedAnimation-->
<transition-group v-if="settings.mainNeedAnimation" name="breadcrumb">
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
<span v-if="item.redirect === 'noRedirect' || index === levelList.length - 1" class="no-redirect">
{{ item.meta?.title }}
</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
<!--no transition-->
<template v-else>
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
<span v-if="item.redirect === 'noRedirect' || index === levelList.length - 1" class="no-redirect">
{{ item.meta?.title }}
</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</template>
</el-breadcrumb>
</template>
<script setup>
import { compile } from 'path-to-regexp'
import setting from '@/settings'
const levelList = ref(null)
//Whether close the animation fo breadcrumb
import { useAppStore } from '@/store/app'
const appStore = useAppStore()
const settings = computed(() => {
return appStore.settings
})
const route = useRoute()
const getBreadcrumb = () => {
// only show routes with meta.title
let matched = route.matched.filter((item) => item.meta && item.meta.title)
const first = matched[0]
if (!isDashboard(first)) {
//it can replace the first page if not exits
matched = [{ path: '/', meta: { title: setting.title } }].concat(matched)
}
levelList.value = matched.filter((item) => item.meta && item.meta.title && item.meta.breadcrumb !== false)
}
const isDashboard = (route) => {
const name = route?.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
}
const pathCompile = (path) => {
const { params } = route
const toPath = compile(path)
return toPath(params)
}
const router = useRouter()
const handleLink = (item) => {
const { redirect, path } = item
if (redirect) {
router.push(redirect)
return
}
if (path) {
router.push(pathCompile(path))
}
}
watch(
() => route.path,
() => {
getBreadcrumb()
},
{ immediate: true }
)
onBeforeMount(() => {
getBreadcrumb()
})
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
line-height: 50px;
margin-left: 8px;
.no-redirect {
color: #97a8be;
cursor: text;
}
}
</style>
这个文件里的主要时读取路由表的路径,可以参考这部分的代码试着写一个三级或者多级路由,v-if="settings.mainNeedAnimation"是项目的配置,可以忽略这部分。
更多推荐
已为社区贡献6条内容
所有评论(0)