From 05525826f073d58ad66524b23757f8b5c6bb9f13 Mon Sep 17 00:00:00 2001 From: Antti Palola Date: Tue, 12 Mar 2024 14:38:36 +0200 Subject: [PATCH] fix: make router useLink link reactive If for example VCard or VListItem `to` prop is evaluated as undefined and then changed, the changes were not be propagated to the href. Breadcrumbs now validates the routes so a fix to tests is required. fixes #19300 --- .../__tests__/VBreadcrumbs.spec.cy.tsx | 5 ++++ packages/vuetify/src/composables/router.tsx | 24 ++++++++++++------- 2 files changed, 20 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 f0cdedd9b694..0f2f228f1af7 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 b59d3c672a94..bf6b5d854790 100644 --- a/packages/vuetify/src/composables/router.tsx +++ b/packages/vuetify/src/composables/router.tsx @@ -64,22 +64,28 @@ 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 toPropRef = computed(() => props.to ? props.to : {}) + const linkProps = computed(() => ({ ...props, to: toPropRef })) - 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), } }