39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
import { computed } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
export interface Breadcrumb {
|
|
title: string
|
|
to?: string
|
|
disabled?: boolean
|
|
}
|
|
|
|
/**
|
|
* Builds a breadcrumb trail from `meta.breadcrumb` on the matched route chain,
|
|
* so pages don't need to know their own position in the hierarchy.
|
|
*/
|
|
export function useBreadcrumbs() {
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const breadcrumbs = computed<Breadcrumb[]>(() => {
|
|
const matched = route.matched.filter((record) => {
|
|
return record.meta.breadcrumb
|
|
})
|
|
|
|
const paths = matched.map((record, index): Breadcrumb => {
|
|
const { breadcrumb } = record.meta
|
|
const title = typeof breadcrumb === 'function' ? breadcrumb(route) : (breadcrumb as string)
|
|
const isLast = index === matched.length - 1
|
|
const to = !isLast && record.name ? router.resolve({ name: record.name, params: route.params }).path : undefined
|
|
|
|
return { title, to, disabled: isLast }
|
|
})
|
|
|
|
const value: Breadcrumb[] = []
|
|
value.push({ title: 'Home', to: '/', disabled: paths.length === 0 })
|
|
return value.concat(paths)
|
|
})
|
|
|
|
return { breadcrumbs }
|
|
}
|