1
- import { h } from 'vue'
2
- import type { FunctionalComponent , HTMLAttributes , VNode } from 'vue'
3
- import { useRouter } from 'vue-router'
1
+ import { computed , defineComponent , h } from 'vue'
2
+ import type { SlotsType , VNode } from 'vue'
3
+ import { useRoute , useRouter } from 'vue-router'
4
4
import { resolveRoutePath } from '../router/index.js'
5
- import { withBase } from '../utils/index.js'
6
5
7
6
/**
8
7
* Forked from https://github.com/vuejs/router/blob/941b2131e80550009e5221d4db9f366b1fea3fd5/packages/router/src/RouterLink.ts#L293
@@ -23,7 +22,7 @@ const guardEvent = (event: MouseEvent): boolean | void => {
23
22
return true
24
23
}
25
24
26
- export interface RouteLinkProps extends HTMLAttributes {
25
+ export interface RouteLinkProps {
27
26
/**
28
27
* Whether the link is active to have an active class
29
28
*
@@ -53,42 +52,61 @@ export interface RouteLinkProps extends HTMLAttributes {
53
52
*
54
53
* It's recommended to use `RouteLink` in VuePress.
55
54
*/
56
- export const RouteLink : FunctionalComponent <
57
- RouteLinkProps ,
58
- Record < never , never > ,
59
- {
60
- default : ( ) => string | VNode | ( string | VNode ) [ ]
61
- }
62
- > = (
63
- { active = false , activeClass = 'route-link-active' , to, ...attrs } ,
64
- { slots } ,
65
- ) => {
66
- const router = useRouter ( )
67
- const resolvedPath = resolveRoutePath ( to )
55
+ export const RouteLink = defineComponent ( {
56
+ name : 'RouteLink' ,
68
57
69
- const path =
70
- // only anchor or query
71
- resolvedPath . startsWith ( '#' ) || resolvedPath . startsWith ( '?' )
72
- ? resolvedPath
73
- : withBase ( resolvedPath )
58
+ props : {
59
+ /**
60
+ * The route path to link to
61
+ */
62
+ to : {
63
+ type : String ,
64
+ required : true ,
65
+ } ,
74
66
75
- return h (
76
- 'a' ,
77
- {
78
- ...attrs ,
79
- class : [ 'route-link' , { [ activeClass ] : active } ] ,
80
- href : path ,
81
- onClick : ( event : MouseEvent = { } as MouseEvent ) => {
82
- guardEvent ( event ) ? router . push ( to ) . catch ( ) : Promise . resolve ( )
83
- } ,
67
+ /**
68
+ * Whether the link is active to have an active class
69
+ *
70
+ * Notice that the active status is not automatically determined according to the current route.
71
+ */
72
+ active : Boolean ,
73
+
74
+ /**
75
+ * The class to add when the link is active
76
+ */
77
+ activeClass : {
78
+ type : String ,
79
+ default : 'route-link-active' ,
84
80
} ,
85
- slots . default ?.( ) ,
86
- )
87
- }
81
+ } ,
88
82
89
- RouteLink . displayName = 'RouteLink'
90
- RouteLink . props = {
91
- active : Boolean ,
92
- activeClass : String ,
93
- to : String ,
94
- }
83
+ slots : Object as SlotsType < {
84
+ default : ( ) => string | VNode | ( string | VNode ) [ ]
85
+ } > ,
86
+
87
+ setup ( props , { slots } ) {
88
+ const router = useRouter ( )
89
+ const route = useRoute ( )
90
+
91
+ const path = computed ( ( ) =>
92
+ props . to . startsWith ( '#' ) || props . to . startsWith ( '?' )
93
+ ? props . to
94
+ : `${ __VUEPRESS_BASE__ } ${ resolveRoutePath ( props . to , route . path ) . substring ( 1 ) } ` ,
95
+ )
96
+
97
+ return ( ) =>
98
+ h (
99
+ 'a' ,
100
+ {
101
+ class : [ 'route-link' , { [ props . activeClass ] : props . active } ] ,
102
+ href : path . value ,
103
+ onClick : ( event : MouseEvent = { } as MouseEvent ) => {
104
+ if ( guardEvent ( event ) ) {
105
+ router . push ( props . to ) . catch ( )
106
+ }
107
+ } ,
108
+ } ,
109
+ slots . default ?.( ) ,
110
+ )
111
+ } ,
112
+ } )
0 commit comments