1
1
/**
2
2
* @jest -environment jsdom
3
3
*/
4
- import { RouterLink } from '../src/RouterLink'
4
+ import { RouterLink , RouterLinkProps } from '../src/RouterLink'
5
5
import {
6
6
START_LOCATION_NORMALIZED ,
7
7
RouteQueryAndHash ,
@@ -10,7 +10,7 @@ import {
10
10
} from '../src/types'
11
11
import { createMemoryHistory , RouterOptions } from '../src'
12
12
import { mount , createMockedRoute } from './mount'
13
- import { nextTick } from 'vue'
13
+ import { defineComponent , nextTick , PropType } from 'vue'
14
14
import { RouteRecordNormalized } from '../src/matcher/types'
15
15
import { routerKey } from '../src/injectionSymbols'
16
16
import { tick } from './utils'
@@ -858,5 +858,97 @@ describe('RouterLink', () => {
858
858
859
859
expect ( wrapper . html ( ) ) . not . toContain ( '</a>' )
860
860
} )
861
+
862
+ describe ( 'Extending RouterLink' , ( ) => {
863
+ const AppLink = defineComponent ( {
864
+ template : `
865
+ <a v-if="isExternalLink" v-bind="$attrs" :href="to">
866
+ <slot />
867
+ </a>
868
+ <router-link v-else v-bind="$props" custom v-slot="{ isActive, href, navigate }">
869
+ <a
870
+ v-bind="$attrs"
871
+ :href="href"
872
+ @click="navigate"
873
+ :class="isActive ? activeClass : inactiveClass"
874
+ >
875
+ <slot />
876
+ </a>
877
+ </router-link>
878
+ ` ,
879
+ components : { RouterLink } ,
880
+ name : 'AppLink' ,
881
+
882
+ // @ts -ignore
883
+ props : {
884
+ ...( ( RouterLink as any ) . props as RouterLinkProps ) ,
885
+ inactiveClass : String as PropType < string > ,
886
+ } ,
887
+
888
+ computed : {
889
+ isExternalLink ( ) : boolean {
890
+ // @ts -ignore
891
+ return typeof this . to === 'string' && this . to . startsWith ( 'http' )
892
+ } ,
893
+ } ,
894
+ } )
895
+
896
+ async function factoryCustom (
897
+ currentLocation : RouteLocationNormalized ,
898
+ propsData : any ,
899
+ resolvedLocation : RouteLocationResolved ,
900
+ slotTemplate : string = ''
901
+ ) {
902
+ const route = createMockedRoute ( currentLocation )
903
+ const router = {
904
+ history : createMemoryHistory ( ) ,
905
+ createHref ( to : RouteLocationNormalized ) : string {
906
+ return this . history . base + to . fullPath
907
+ } ,
908
+ options : { } as Partial < RouterOptions > ,
909
+ resolve : jest . fn ( ) ,
910
+ push : jest . fn ( ) . mockResolvedValue ( resolvedLocation ) ,
911
+ }
912
+ router . resolve . mockReturnValueOnce ( resolvedLocation )
913
+
914
+ const wrapper = await mount ( AppLink , {
915
+ propsData,
916
+ provide : {
917
+ [ routerKey as any ] : router ,
918
+ ...route . provides ,
919
+ } ,
920
+ slots : { default : slotTemplate } ,
921
+ } )
922
+
923
+ return { router, wrapper, route }
924
+ }
925
+
926
+ it ( 'can extend RouterLink with inactive class' , async ( ) => {
927
+ const { wrapper } = await factoryCustom (
928
+ locations . basic . normalized ,
929
+ {
930
+ to : locations . basic . string ,
931
+ inactiveClass : 'inactive' ,
932
+ activeClass : 'active' ,
933
+ } ,
934
+ locations . foo . normalized
935
+ )
936
+
937
+ expect ( wrapper . find ( 'a' ) ! . className ) . toEqual ( 'inactive' )
938
+ } )
939
+
940
+ it ( 'can extend RouterLink with external link' , async ( ) => {
941
+ const { wrapper } = await factoryCustom (
942
+ locations . basic . normalized ,
943
+ {
944
+ to : 'https://esm.dev' ,
945
+ } ,
946
+ locations . foo . normalized
947
+ )
948
+
949
+ expect ( wrapper . find ( 'a' ) ! . className ) . toEqual ( '' )
950
+ expect ( wrapper . find ( 'a' ) ! . href ) . toEqual ( 'https://esm.dev/' )
951
+ } )
952
+ } )
861
953
} )
862
954
} )
0 commit comments