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'
44import { resolveRoutePath } from '../router/index.js'
5- import { withBase } from '../utils/index.js'
65
76/**
87 * 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 => {
2322 return true
2423}
2524
26- export interface RouteLinkProps extends HTMLAttributes {
25+ export interface RouteLinkProps {
2726 /**
2827 * Whether the link is active to have an active class
2928 *
@@ -53,42 +52,61 @@ export interface RouteLinkProps extends HTMLAttributes {
5352 *
5453 * It's recommended to use `RouteLink` in VuePress.
5554 */
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' ,
6857
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+ } ,
7466
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' ,
8480 } ,
85- slots . default ?.( ) ,
86- )
87- }
81+ } ,
8882
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