diff --git a/docs/guide/markdown.md b/docs/guide/markdown.md
index bb5947852f7..523c7a3e0fe 100644
--- a/docs/guide/markdown.md
+++ b/docs/guide/markdown.md
@@ -62,11 +62,11 @@ Take our documentation source files as an example:
```vue
- Home
- Config Reference
- Getting Started
- Guide
- Config Reference > markdown.links
+ Home
+ Config Reference
+ Getting Started
+ Guide
+ Config Reference > markdown.links
GitHub
```
@@ -82,7 +82,7 @@ Take our documentation source files as an example:
**Explanation**
-- Internal links will be converted to `` for SPA navigation.
+- Internal links will be converted to `` which is similar to `` for SPA navigation.
- Internal links to `.md` files will be converted to the [page route path](./page.md#routing), and both absolute path and relative path are supported.
- External links will get `target="_blank" rel="noopener noreferrer"` attrs.
diff --git a/docs/reference/components.md b/docs/reference/components.md
index 64f5231a5c6..ca5b46cba2a 100644
--- a/docs/reference/components.md
+++ b/docs/reference/components.md
@@ -26,7 +26,7 @@
- Props:
- pageKey
- Type: `string`
- - Required: `false`
+ - Required: No`
- Usage:
@@ -44,3 +44,24 @@
- Also see:
- [Node API > Page Properties > key](./node-api.md#key)
+
+## VPLink
+
+- Props:
+ - to
+ - Type: `string`
+ - Required: Yes
+
+- Usage:
+
+```md
+
+```
+
+- Details:
+
+ This component will render an `` link that has SPA navigation capabilities, and will trigger `router.push` when clicked.
+
+ Its `to` property is the link to navigate to.
+
+ This component is mainly used to replace ``, which has expensive initialization. If you need to place internal links and don't care about its exact rendering href and activate state, you should use it as first choice.
diff --git a/docs/reference/config.md b/docs/reference/config.md
index 7dc3bc98cd6..bc503a5f80a 100644
--- a/docs/reference/config.md
+++ b/docs/reference/config.md
@@ -586,7 +586,7 @@ const defaultOptions = {
Options for VuePress built-in markdown-it links plugin.
- It will convert internal links to ``, and add extra attributes and icon to external links.
+ It will convert internal links to `` (similar to `` with SPA navigation support), and add extra attributes and icon to external links.
Set to `false` to disable this plugin.
@@ -595,15 +595,17 @@ const defaultOptions = {
#### markdown.links.internalTag
-- Type: `'a' | 'RouterLink'`
+- Type: `'a' | 'RouterLink' | 'VPLink'`
-- Default: `'RouterLink'`
+- Default: `'VPLink'`
- Details:
Tag for internal links.
- By default, this plugin will transform internal links to ``. You can set this option to `'a'` to disable this feature.
+ By default, this plugin will transform internal links to `` with SPA navigation support.
+
+ You can set this option to `'RouterLink'` for standard router link with exact route resolving and active and exactActive state, or set this option to `'a'` to disable this feature.
#### markdown.links.externalAttrs
diff --git a/docs/reference/plugin/toc.md b/docs/reference/plugin/toc.md
index 21f65f2a7b5..5000b0f3720 100644
--- a/docs/reference/plugin/toc.md
+++ b/docs/reference/plugin/toc.md
@@ -105,7 +105,7 @@ interface TocPropsOptions {
containerClass: string
listClass: string
itemClass: string
- linkTag: 'a' | 'RouterLink'
+ linkTag: 'a' | 'RouterLink' | 'VPLink'
linkClass: string
linkActiveClass: string
linkChildrenActiveClass: string
@@ -122,7 +122,7 @@ const defaultOptions = {
containerClass: 'vuepress-toc',
listClass: 'vuepress-toc-list',
itemClass: 'vuepress-toc-item',
- linkTag: 'RouterLink',
+ linkTag: 'VPLink',
linkClass: 'vuepress-toc-link',
linkActiveClass: 'active',
linkChildrenActiveClass: 'active',
@@ -148,18 +148,18 @@ const defaultOptions = {
- Foo
+ Foo
- Bar
+ Bar
diff --git a/docs/zh/guide/markdown.md b/docs/zh/guide/markdown.md
index bee8e9cee52..574cfbc9fe6 100644
--- a/docs/zh/guide/markdown.md
+++ b/docs/zh/guide/markdown.md
@@ -63,11 +63,11 @@ VuePress 会使用 [markdown-it](https://github.com/markdown-it/markdown-it) 来
```vue
- 首页
- 配置参考
- 快速上手
- 指南
- 配置参考 > markdown.links
+ 首页
+ 配置参考
+ 快速上手
+ 指南
+ 配置参考 > markdown.links
GitHub
```
@@ -83,7 +83,7 @@ VuePress 会使用 [markdown-it](https://github.com/markdown-it/markdown-it) 来
**解释**
-- 内部链接会被转换为 `` 以便进行 SPA 导航。
+- 内部链接会被转换为和 `` 类似的 `` 以便进行 SPA 导航。
- 指向 `.md` 文件的内部链接会被转换为目标页面的 [路由路径](./page.md#路由),并且支持绝对路径和相对路径。
- 外部链接会被添加 `target="_blank" rel="noopener noreferrer"` 属性。
diff --git a/docs/zh/reference/components.md b/docs/zh/reference/components.md
index 3b2a3145b33..70f584615ba 100644
--- a/docs/zh/reference/components.md
+++ b/docs/zh/reference/components.md
@@ -18,15 +18,15 @@
如果一个组件在 `setup()` 中直接使用 浏览器 / DOM API ,它会导致构建过程报错,因为这些 API 在 Node.js 的环境中是无法使用的。在这种情况下,你可以选择一种方式:
- - 修改这个组件,只在 `onBeforeMount()` 或 `onMounted()` Hook 中使用 浏览器 / DOM API 。
+ - 修改这个组件,只在 `onBeforeMount()` 或 `onMounted()` Hook 中使用 浏览器 / DOM API 。
- 使用 `` 包裹这个组件。
## Content
-- Props:
+- 属性:
- pageKey
- 类型: `string`
- - 是否必须: `false`
+ - 必要: 否
- 使用:
@@ -44,3 +44,24 @@
- 参考:
- [Node API > Page 属性 > key](./node-api.md#key)
+
+## VPLink
+
+- 属性:
+ - to
+ - 类型: `string`
+ - 必要: 是
+
+- 使用:
+
+```md
+
+```
+
+- 详情:
+
+ 该组件会渲染一个拥有 SPA 导航能力的 `` 链接,点击时会触发 `router.push` 行为。
+
+ 它的 `to` 属性是需要导航到的链接。
+
+ 该组件主要用于替代初始化开销过大的 `` ,如果你需要放置内部链接且不关注准确的解析地址以及激活状态,你应该首选使用它。
diff --git a/docs/zh/reference/config.md b/docs/zh/reference/config.md
index b5a323ed419..948317b9327 100644
--- a/docs/zh/reference/config.md
+++ b/docs/zh/reference/config.md
@@ -599,7 +599,7 @@ const defaultOptions = {
VuePress 内置的 markdown-it 链接插件的配置项。
- 它可以把站内链接转换为 `` ,并且可以在站外链接上添加额外的属性和图标。
+ 它可以把站内链接转换为 `` (类似于 ``,提供 SPA 导航) ,并且可以在站外链接上添加额外的属性和图标。
设置为 `false` 可以禁用该插件。
@@ -608,15 +608,17 @@ const defaultOptions = {
#### markdown.links.internalTag
-- 类型: `string`
+- 类型: `'a' | 'RouterLink' | 'VPLink'`
-- 默认值: `'RouterLink'`
+- 默认值: `'VPLink'`
- 详情:
内部链接所使用的标签。
- 默认情况下,该插件会把内部链接转换为 `` 。你可以把该选项设置为 `'a'` 来禁用这个功能。
+ 默认情况下,该插件会把内部链接转换为 ``,以提供 SPA 导航。
+
+ 你可以将该选项设置为 `'RouterLink'` 来渲染为带有准确路由解析以及激活和准确激活状态的 ``。也可以将该选项设置为 `'a'` 来禁用这个功能。
#### markdown.links.externalAttrs
diff --git a/docs/zh/reference/plugin/toc.md b/docs/zh/reference/plugin/toc.md
index f6ede78ddd1..07cac755ac2 100644
--- a/docs/zh/reference/plugin/toc.md
+++ b/docs/zh/reference/plugin/toc.md
@@ -105,7 +105,7 @@ interface TocPropsOptions {
containerClass: string
listClass: string
itemClass: string
- linkTag: 'a' | 'RouterLink'
+ linkTag: 'a' | 'RouterLink' | 'VPLink'
linkClass: string
linkActiveClass: string
linkChildrenActiveClass: string
@@ -122,7 +122,7 @@ const defaultOptions = {
containerClass: 'vuepress-toc',
listClass: 'vuepress-toc-list',
itemClass: 'vuepress-toc-item',
- linkTag: 'RouterLink',
+ linkTag: 'VPLink',
linkClass: 'vuepress-toc-link',
linkActiveClass: 'active',
linkChildrenActiveClass: 'active',
@@ -148,18 +148,18 @@ const defaultOptions = {
- Foo
+ Foo
- Bar
+ Bar
diff --git a/ecosystem/plugin-external-link-icon/tests/node/externalLinkIconPlugin.spec.ts b/ecosystem/plugin-external-link-icon/tests/node/externalLinkIconPlugin.spec.ts
index fd978c8c3a5..3cb3008dc45 100644
--- a/ecosystem/plugin-external-link-icon/tests/node/externalLinkIconPlugin.spec.ts
+++ b/ecosystem/plugin-external-link-icon/tests/node/externalLinkIconPlugin.spec.ts
@@ -39,7 +39,7 @@ describe('@vuepress/plugin-external-link-icon > node > externalLinkIconPlugin',
'github',
'https://github.com',
'http://github.com',
- 'foo',
+ 'foo',
]
.map((a) => `${a}
`)
.join('\n') + '\n',
@@ -66,7 +66,7 @@ describe('@vuepress/plugin-external-link-icon > node > externalLinkIconPlugin',
'github',
'https://github.com',
'http://github.com',
- 'foo',
+ 'foo',
]
.map((a) => `${a}
`)
.join('\n') + '\n',
@@ -87,7 +87,7 @@ describe('@vuepress/plugin-external-link-icon > node > externalLinkIconPlugin',
'github',
'https://github.com',
'http://github.com',
- 'foo',
+ 'foo',
]
.map((a) => `${a}
`)
.join('\n') + '\n',
diff --git a/ecosystem/plugin-toc/src/client/components/Toc.ts b/ecosystem/plugin-toc/src/client/components/Toc.ts
index 36f118dfa6b..40889ce9595 100644
--- a/ecosystem/plugin-toc/src/client/components/Toc.ts
+++ b/ecosystem/plugin-toc/src/client/components/Toc.ts
@@ -1,8 +1,8 @@
import { usePageData } from '@vuepress/client'
import type { PageHeader } from '@vuepress/client'
-import { computed, defineComponent, h, toRefs } from 'vue'
+import { computed, defineComponent, h, resolveComponent, toRefs } from 'vue'
import type { PropType, VNode } from 'vue'
-import { RouterLink, useRoute } from 'vue-router'
+import { useRoute } from 'vue-router'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import type { TocPropsOptions } from '../../shared/index.js'
@@ -34,26 +34,26 @@ const renderLink = (
linkClass.push(options.linkChildrenActiveClass)
}
- if (options.linkTag === 'RouterLink') {
+ if (options.linkTag === 'a') {
return h(
- RouterLink,
+ 'a',
{
- to: hash,
+ href: hash,
class: linkClass,
ariaLabel: header.title,
},
- () => header.title,
+ header.title,
)
}
return h(
- 'a',
+ resolveComponent(options.linkTag),
{
- href: hash,
+ to: hash,
class: linkClass,
ariaLabel: header.title,
},
- header.title,
+ () => header.title,
)
}
@@ -123,7 +123,7 @@ export const Toc = defineComponent({
containerClass: 'vuepress-toc',
listClass: 'vuepress-toc-list',
itemClass: 'vuepress-toc-item',
- linkTag: 'RouterLink',
+ linkTag: 'VPLink',
linkClass: 'vuepress-toc-link',
linkActiveClass: 'active',
linkChildrenActiveClass: 'active',
diff --git a/ecosystem/plugin-toc/src/shared/types.ts b/ecosystem/plugin-toc/src/shared/types.ts
index 4ad02f3a216..88cdfe4163d 100644
--- a/ecosystem/plugin-toc/src/shared/types.ts
+++ b/ecosystem/plugin-toc/src/shared/types.ts
@@ -3,7 +3,7 @@ export interface TocPropsOptions {
containerClass: string
listClass: string
itemClass: string
- linkTag: 'a' | 'RouterLink'
+ linkTag: 'a' | 'RouterLink' | 'VPLink'
linkClass: string
linkActiveClass: string
linkChildrenActiveClass: string
diff --git a/ecosystem/theme-default/src/client/components/AutoLink.vue b/ecosystem/theme-default/src/client/components/AutoLink.vue
index b6d8e404f3f..1e493b6fbe4 100644
--- a/ecosystem/theme-default/src/client/components/AutoLink.vue
+++ b/ecosystem/theme-default/src/client/components/AutoLink.vue
@@ -9,7 +9,7 @@ export default defineComponent({
- {
{{ item.text }}
-
+
{
-
+
{
>
{{ navbarBrandTitle }}
-
+
diff --git a/ecosystem/theme-default/src/client/composables/index.ts b/ecosystem/theme-default/src/client/composables/index.ts
index 568299036a0..f960363b9c8 100644
--- a/ecosystem/theme-default/src/client/composables/index.ts
+++ b/ecosystem/theme-default/src/client/composables/index.ts
@@ -1,6 +1,5 @@
export * from './useDarkMode.js'
export * from './useNavLink.js'
-export * from './useResolveRouteWithRedirect.js'
export * from './useScrollPromise.js'
export * from './useSidebarItems.js'
export * from './useThemeData.js'
diff --git a/ecosystem/theme-default/src/client/composables/useResolveRouteWithRedirect.ts b/ecosystem/theme-default/src/client/composables/useResolveRouteWithRedirect.ts
deleted file mode 100644
index 297b0e95a68..00000000000
--- a/ecosystem/theme-default/src/client/composables/useResolveRouteWithRedirect.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { isFunction, isString } from '@vuepress/shared'
-import { useRouter } from 'vue-router'
-import type { Router } from 'vue-router'
-
-/**
- * Resolve a route with redirection
- */
-export const useResolveRouteWithRedirect = (
- ...args: Parameters
-): ReturnType => {
- const router = useRouter()
- const route = router.resolve(...args)
- const lastMatched = route.matched[route.matched.length - 1]
- if (!lastMatched?.redirect) {
- return route
- }
- const { redirect } = lastMatched
- const resolvedRedirect = isFunction(redirect) ? redirect(route) : redirect
- const resolvedRedirectObj = isString(resolvedRedirect)
- ? { path: resolvedRedirect }
- : resolvedRedirect
- return useResolveRouteWithRedirect({
- hash: route.hash,
- query: route.query,
- params: route.params,
- ...resolvedRedirectObj,
- })
-}
diff --git a/ecosystem/theme-default/src/client/layouts/NotFound.vue b/ecosystem/theme-default/src/client/layouts/NotFound.vue
index 4bc7904808c..767660c3466 100644
--- a/ecosystem/theme-default/src/client/layouts/NotFound.vue
+++ b/ecosystem/theme-default/src/client/layouts/NotFound.vue
@@ -1,5 +1,5 @@