From 7cca1b51c61bc84e6be1954de3c9cbd335395c27 Mon Sep 17 00:00:00 2001 From: Antti <100124171+Antti-Palola@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:46:17 +0200 Subject: [PATCH] fix(router): make useLink link reactive (#19386) fixes #19300 --- .../__tests__/VBreadcrumbs.spec.cy.tsx | 5 ++++ packages/vuetify/src/composables/router.tsx | 23 +++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/vuetify/src/components/VBreadcrumbs/__tests__/VBreadcrumbs.spec.cy.tsx b/packages/vuetify/src/components/VBreadcrumbs/__tests__/VBreadcrumbs.spec.cy.tsx index f0cdedd9b69..0f2f228f1af 100644 --- a/packages/vuetify/src/components/VBreadcrumbs/__tests__/VBreadcrumbs.spec.cy.tsx +++ b/packages/vuetify/src/components/VBreadcrumbs/__tests__/VBreadcrumbs.spec.cy.tsx @@ -109,6 +109,11 @@ describe('VBreadcrumbs', () => { cy.then(() => { expect(router.currentRoute.value.path).to.equal('/about') }) + + // Return back to root to not break succeeding tests that don't have /about path. + cy.get('.v-breadcrumbs').then(() => { + router.push('/') + }) }) it('should apply active color', () => { diff --git a/packages/vuetify/src/composables/router.tsx b/packages/vuetify/src/composables/router.tsx index b59d3c672a9..09dbb0bcbf7 100644 --- a/packages/vuetify/src/composables/router.tsx +++ b/packages/vuetify/src/composables/router.tsx @@ -64,22 +64,27 @@ export function useLink (props: LinkProps & LinkListeners, attrs: SetupContext[' href: toRef(props, 'href'), } } + // vue-router useLink `to` prop needs to be reactive and useLink will crash if undefined + const linkProps = computed(() => ({ ...props, to: props.to ? props.to : {} })) - const link = props.to ? RouterLink.useLink(props as UseLinkOptions) : undefined + const routerLink = RouterLink.useLink(linkProps.value as UseLinkOptions) + // Actual link needs to be undefined when to prop is not used + const link = computed(() => props.to ? routerLink : undefined) const route = useRoute() return { isLink, isClickable, - route: link?.route, - navigate: link?.navigate, - isActive: link && computed(() => { - if (!props.exact) return link.isActive?.value - if (!route.value) return link.isExactActive?.value - - return link.isExactActive?.value && deepEqual(link.route.value.query, route.value.query) + route: link.value?.route, + navigate: link.value?.navigate, + isActive: computed(() => { + if (!link.value) return false + if (!props.exact) return link.value.isActive?.value ?? false + if (!route.value) return link.value.isExactActive?.value ?? false + + return link.value.isExactActive?.value && deepEqual(link.value.route.value.query, route.value.query) }), - href: computed(() => props.to ? link?.route.value.href : props.href), + href: computed(() => props.to ? link.value?.route.value.href : props.href), } }