Vue3路由面包屑怎么动态显示父级路径?
我在用Vue3+Vue Router做面包屑导航时遇到了问题。项目是嵌套路由结构,比如访问/articles/123时,面包屑应该显示「首页 > 文章列表 > 文章详情」,但实际只显示了当前路由的name。
我尝试在路由配置里添加meta.breadcrumb字段,然后用递归组件渲染。但当访问子路由时,父级路径的meta信息拿不到,导致只能显示最后一层。这是代码:
<template>
<div>
<router-link
v-for="(crumb, i) in breadcrumbs"
:key="i"
:to="crumb.path"
>
{{ crumb.name }}
</router-link>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const breadcrumbs = computed(() => {
return route.matched.map(r => ({
name: r.meta.title,
path: r.path
}))
})
</script>
路由配置是这样的:articles列表的path是/articles,详情页是/articles/:id。但访问/articles/123时,matched数组里只有详情页的路由对象,缺少父级/articles的路由信息,这是为什么啊?
matched数组是基于路由的层级关系生成的,如果你的路由配置里没有明确声明父子关系,它就只会匹配到当前路由,而不会包含父级。解决方法很简单,在路由配置里用
children明确声明父子关系。比如你的/articles和/articles/:id应该这样写:注意这里的关键点是,子路由
:id被放在了父路由/articles的children里面。这样当访问/articles/123时,route.matched会包含两个对象:一个是父路由/articles,另一个是子路由:id。你的面包屑逻辑就能正常工作了。另外,你现在的
meta.title是直接取值的,但有时候可能需要动态生成面包屑内容,比如显示文章标题。这种情况下可以改一下逻辑,让meta.breadcrumb支持函数。举个例子:然后在路由配置里,你可以这样定义动态标题:
最后提醒一点,服务端渲染的项目要特别注意路由的加载顺序,确保所有路由都在应用初始化时加载完成,否则可能会导致
matched数组不完整。这个问题我之前踩过坑,折腾了好久才找到原因,希望你能少走点弯路。