Vue-Element-Admin Breadcrumb Generation Algorithm: Handling Nested Routes with Route Meta
The breadcrumb generation algorithm in PanJiaChen/vue-element-admin dynamically assembles navigation trails by filtering this.$route.matched for records containing meta.title, prepending a Dashboard entry when needed, and respecting meta.breadcrumb: false to hide specific nested routes.
Vue-element-admin constructs breadcrumbs through systematic traversal of matched route records rather than static configuration. The implementation lives in src/components/Breadcrumb/index.vue and leverages Vue Router's matched array to automatically reflect nested hierarchies. This approach allows developers to control breadcrumb visibility and labels directly through route meta properties without modifying component logic.
How the Breadcrumb Generation Algorithm Works
The core algorithm follows a four-step filtration process inside the getBreadcrumb() method. It begins by extracting the hierarchy from the current route object.
Step 1: Collect Matched Routes with Meta Titles
The algorithm accesses this.$route.matched, which contains every route record from root to deepest child. It immediately filters this array to keep only entries that define a display title.
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
This ensures that routes without human-readable labels never appear in the breadcrumb trail.
Step 2: Ensure Dashboard Root Entry
If the first matched record is not the dashboard route, the algorithm injects a synthetic Dashboard entry at the beginning of the array. This guarantees the breadcrumb always starts at the home page.
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' } }].concat(matched)
}
The isDashboard() helper checks the route name case-insensitively to determine if the root is already present.
Step 3: Filter by Breadcrumb Visibility Flag
Routes can opt out of breadcrumb display by setting meta.breadcrumb: false. The final list removes these entries while preserving the hierarchy of visible parents.
this.levelList = matched.filter(
item => item.meta && item.meta.title && item.meta.breadcrumb !== false
)
The resulting levelList array drives the template rendering.
Step 4: Render with Navigation Logic
The template iterates levelList, rendering each item as plain text if it is the last item or has redirect: 'noRedirect', otherwise as a clickable link.
<el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group 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>
</el-breadcrumb>
Handling Nested Routes with Route Meta Properties
Nested routes in vue-element-admin are defined under src/router/modules/nested.js. The breadcrumb algorithm naturally handles arbitrary depth because this.$route.matched preserves parent-child ordering.
Route Configuration Example
Consider this three-level nested structure:
{
path: '/nested',
component: Layout,
redirect: '/nested/menu1',
name: 'Nested',
meta: { title: 'Nested', icon: 'nested' },
children: [
{
path: 'menu1',
name: 'Menu1',
meta: { title: 'Menu 1' },
children: [
{
path: 'menu1-2',
name: 'Menu1-2',
meta: { title: 'Menu 1-2' },
children: [
{ path: 'menu1-2-1', name: 'Menu1-2-1', meta: { title: 'Menu 1-2-1' } }
]
}
]
}
]
}
When navigating to /nested/menu1/menu1-2/menu1-2-1, the matched array contains four records: /nested, /nested/menu1, /nested/menu1/menu1-2, and the final leaf route. The algorithm transforms this into:
Dashboard / Nested / Menu 1 / Menu 1-2 / Menu 1-2-1
Controlling Visibility with meta.breadcrumb
Developers can hide intermediate steps by setting breadcrumb: false in the route meta:
{
path: 'menu1-2-1',
name: 'Menu1-2-1',
meta: { title: 'Menu 1-2-1', breadcrumb: false }
}
With this configuration, navigating to the same URL produces:
Dashboard / Nested / Menu 1 / Menu 1-2
The leaf route still renders its view, but disappears from the breadcrumb trail, allowing cleaner UI for modal-like or utility routes.
Source Code Implementation
The complete logic resides in src/components/Breadcrumb/index.vue, which is imported and displayed in src/layout/components/Navbar.vue. Beyond the filtration steps, the component handles dynamic path compilation for parameterized routes.
Path Compilation for Dynamic Segments
The pathCompile() method uses path-to-regexp to resolve routes containing parameters like /user/:id:
pathCompile(path) {
const { params } = this.$route
const toPath = require('path-to-regexp').compile(path)
return toPath(params)
}
When users click a breadcrumb item, handleLink() either follows an explicit redirect or compiles the path dynamically:
handleLink(item) {
if (item.redirect) return this.$router.push(item.redirect)
this.$router.push(this.pathCompile(item.path))
}
Full getBreadcrumb Method
Here is the complete algorithm implementation as found in the source:
methods: {
getBreadcrumb() {
// Collect routes with titles
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
// Prepend Dashboard if not present
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' } }].concat(matched)
}
// Apply breadcrumb visibility filter
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
},
isDashboard(route) {
const name = route && route.name
return name && name.trim().toLowerCase() === 'dashboard'.toLowerCase()
}
}
Summary
- The algorithm sources data from
this.$route.matched, which automatically includes all parent routes in nested hierarchies. - Route meta properties drive the entire breadcrumb system:
meta.titleprovides display text, whilemeta.breadcrumb: falsehides entries. - The Dashboard route serves as a synthetic root; the algorithm prepends it automatically when missing from the matched array.
- Path compilation via
path-to-regexpenables breadcrumbs to link correctly to parameterized routes. - Implementation resides in
src/components/Breadcrumb/index.vue, with route definitions typically located insrc/router/modules/nested.js.
Frequently Asked Questions
How does vue-element-admin handle deeply nested routes in breadcrumbs?
The breadcrumb generation algorithm handles arbitrary nesting depth naturally because Vue Router's this.$route.matched array already orders routes from parent to child. When you navigate to /nested/menu1/menu1-2/menu1-2-1, the matched array contains every level of the hierarchy, and the algorithm filters and renders each one that has meta.title, resulting in a complete trail from Dashboard to the deepest leaf.
Can I hide specific routes from the breadcrumb without removing them from the router?
Yes. Set meta.breadcrumb: false in the route configuration. The algorithm explicitly checks for this flag in the final filtration step: item.meta.breadcrumb !== false. This allows utility routes or modal pages to remain accessible via URL while keeping the breadcrumb trail clean and focused on primary navigation paths.
Why does the breadcrumb always show Dashboard even when I'm not on that route?
The algorithm enforces Dashboard as the root entry via a prepend operation. In getBreadcrumb(), it checks if (!this.isDashboard(first)) and inserts { path: '/dashboard', meta: { title: 'Dashboard' } } at the beginning of the matched array. This design pattern ensures users always have a visible path back to the home page from any nested location.
How are dynamic route parameters handled in breadcrumb links?
The component uses path-to-regexp to compile parameterized paths dynamically. The pathCompile() method takes the route's path string (e.g., /user/:id) and the current route parameters, then generates the actual URL. When users click a breadcrumb, handleLink() either uses an explicit redirect property or pushes the compiled path to the router, ensuring dynamic segments resolve correctly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →