diff --git a/packages/router/__tests__/RouterLink.spec.ts b/packages/router/__tests__/RouterLink.spec.ts
index bf87c2de7..ccca9fdb1 100644
--- a/packages/router/__tests__/RouterLink.spec.ts
+++ b/packages/router/__tests__/RouterLink.spec.ts
@@ -358,7 +358,8 @@ async function factory(
currentLocation: RouteLocationNormalized,
propsData: any,
resolvedLocation: RouteLocationResolved,
- slotTemplate: string = ''
+ slotTemplate: string = '',
+ component: any = RouterLink
) {
const route = createMockedRoute(currentLocation)
const router = {
@@ -373,7 +374,7 @@ async function factory(
}
router.resolve.mockReturnValueOnce(resolvedLocation)
- const wrapper = mount(RouterLink as any, {
+ const wrapper = mount(component, {
propsData,
global: {
provide: {
@@ -899,6 +900,32 @@ describe('RouterLink', () => {
expect(wrapper.html()).not.toContain('')
})
+ // #2375
+ it('works with custom directive when custom=true', async () => {
+ const Directive = (el: HTMLElement) => el.setAttribute('data-test', 'x')
+ const AppLink = defineComponent({
+ template: `
+
+
+
+ `,
+ components: { RouterLink },
+ directives: { Directive },
+ name: 'AppLink',
+ })
+
+ const { wrapper } = await factory(
+ locations.basic.normalized,
+ { to: locations.basic.string },
+ locations.basic.normalized,
+ undefined,
+ AppLink
+ )
+
+ expect(wrapper.element.tagName).toBe('A')
+ expect(wrapper.attributes('data-test')).toBe('x')
+ })
+
describe('Extending RouterLink', () => {
const AppLink = defineComponent({
template: `
@@ -932,59 +959,31 @@ describe('RouterLink', () => {
},
})
- async function factoryCustom(
- currentLocation: RouteLocationNormalized,
- propsData: any,
- resolvedLocation: RouteLocationResolved,
- slotTemplate: string = ''
- ) {
- const route = createMockedRoute(currentLocation)
- const router = {
- history: createMemoryHistory(),
- createHref(to: RouteLocationNormalized): string {
- return this.history.base + to.fullPath
- },
- options: {} as Partial,
- resolve: vi.fn(),
- push: vi.fn().mockResolvedValue(resolvedLocation),
- }
- router.resolve.mockReturnValueOnce(resolvedLocation)
-
- const wrapper = await mount(AppLink as any, {
- propsData,
- global: {
- provide: {
- [routerKey as any]: router,
- ...route.provides,
- },
- },
- slots: { default: slotTemplate },
- })
-
- return { router, wrapper, route }
- }
-
it('can extend RouterLink with inactive class', async () => {
- const { wrapper } = await factoryCustom(
+ const { wrapper } = await factory(
locations.basic.normalized,
{
to: locations.basic.string,
inactiveClass: 'inactive',
activeClass: 'active',
},
- locations.foo.normalized
+ locations.foo.normalized,
+ undefined,
+ AppLink
)
expect(wrapper.find('a')!.classes()).toEqual(['inactive'])
})
it('can extend RouterLink with external link', async () => {
- const { wrapper } = await factoryCustom(
+ const { wrapper } = await factory(
locations.basic.normalized,
{
to: 'https://esm.dev',
},
- locations.foo.normalized
+ locations.foo.normalized,
+ undefined,
+ AppLink
)
expect(wrapper.find('a')!.classes()).toHaveLength(0)
diff --git a/packages/router/src/RouterLink.ts b/packages/router/src/RouterLink.ts
index 731dfbf75..e9c014196 100644
--- a/packages/router/src/RouterLink.ts
+++ b/packages/router/src/RouterLink.ts
@@ -263,6 +263,10 @@ export function useLink(
}
}
+function preferSingleVNode(vnodes: VNode[]) {
+ return vnodes.length === 1 ? vnodes[0] : vnodes
+}
+
export const RouterLinkImpl = /*#__PURE__*/ defineComponent({
name: 'RouterLink',
compatConfig: { MODE: 3 },
@@ -307,7 +311,7 @@ export const RouterLinkImpl = /*#__PURE__*/ defineComponent({
}))
return () => {
- const children = slots.default && slots.default(link)
+ const children = slots.default && preferSingleVNode(slots.default(link))
return props.custom
? children
: h(