Skip to content

feat(client): use visual routes #1433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/reference/client-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ Client API is provided by [@vuepress/client](https://www.npmjs.com/package/@vuep
- Also see:
- [Guide > Assets > Base Helper](../guide/assets.md#base-helper)


## getPagesPath

- Details:

Returns all pages path, replacement of `router.getRoutes()`.

## isPageExist

- Details:

Returns whether the corresponding path has a page.

## resolve

- Details:

Returns the route and related page metadata corresponding to the path, replacement of `router.resolve()`.

## Constants

There are some constants that available in the client side code.
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ permalinkPattern: :year/:month/:day/:slug.html
- [Frontmatter > permalink](#permalink)
- [Node API > Page Properties > permalink](./node-api.md#permalink)

## routeMeta
## meta

- Type: `Record<string, unknown>`

Expand All @@ -198,7 +198,7 @@ permalinkPattern: :year/:month/:day/:slug.html
Custom data to be attached to the page route.

- Also see:
- [Node API > Page Properties > routeMeta](./node-api.md#routeMeta)
- [Node API > Page Properties > meta](./node-api.md#meta)

## title

Expand Down
6 changes: 3 additions & 3 deletions docs/reference/node-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ interface MarkdownLink {
- [Frontmatter > permalink](./frontmatter.md#permalink)
- [Frontmatter > permalinkPattern](./frontmatter.md#permalinkpattern)

### routeMeta
### meta

- Type: `Record<string, unknown>`

Expand All @@ -614,11 +614,11 @@ interface MarkdownLink {
Custom data to be attached to the route record of vue-router.

- Also see:
- [Frontmatter > routeMeta](./frontmatter.md#routemeta)
- [Frontmatter > meta](./frontmatter.md#meta)
- [vue-router > API Reference > RouteRecordRaw > meta](https://router.vuejs.org/api/#meta)

::: tip What's the difference between route meta and page data?
Both [route meta](#routemeta) and [page data](#data) is available in client side. However, route meta is attached to the route record, so the route meta of all pages would be loaded at once when users enter your site. In the contrast, page data is saved in separated files, which would be loaded only when users enter the corresponding page.
Both [route meta](#meta) and [page data](#data) is available in client side. However, route meta is attached to the route record, so the route meta of all pages would be loaded at once when users enter your site. In the contrast, page data is saved in separated files, which would be loaded only when users enter the corresponding page.

Therefore, it's not recommended to store large amounts of info into route meta, otherwise the initial loading speed will be affected a lot when your site has a large number of pages.
:::
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/plugin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export default {

This hook can be used for adding extra properties or modifying current properties on `Page` object.

Notice that changes to `page.data` and `page.routeMeta` can be used in client side code.
Notice that changes to `page.data` and `page.meta` can be used in client side code.

- Example:

Expand Down Expand Up @@ -325,7 +325,7 @@ export default {
- Also see:
- [Client API > usePageData](./client-api.md#usepagedata)
- [Node API > Page Properties > data](./node-api.md#data)
- [Node API > Page Properties > routeMeta](./node-api.md#routemeta)
- [Node API > Page Properties > meta](./node-api.md#meta)

## Lifecycle Hooks

Expand Down
18 changes: 18 additions & 0 deletions docs/zh/reference/client-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@
- 参考:
- [指南 > 静态资源 > Base Helper](../guide/assets.md#base-helper)

## getPagesPath

- 详情:

返回所有页面路径,替代 `router.getRoutes()`。

## isPageExist

- 详情:

返回对应的路径是否存在相应页面。

## resolve

- 详情:

返回路径对应的最终路径和相关页面的元数据,替代 `router.resolve()`。

## 常量

在客户端代码中有一些常量可以使用。
Expand Down
4 changes: 2 additions & 2 deletions docs/zh/reference/frontmatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ permalinkPattern: :year/:month/:day/:slug.html
- [Frontmatter > permalink](#permalink)
- [Node API > Page 属性 > permalink](./node-api.md#permalink)

## routeMeta
## meta

- 类型: `Record<string, unknown>`

Expand All @@ -198,7 +198,7 @@ permalinkPattern: :year/:month/:day/:slug.html
附加到页面路由的自定义数据。

- 参考:
- [Node API > Page 属性 > routeMeta](./node-api.md#routeMeta)
- [Node API > Page 属性 > meta](./node-api.md#meta)

## title

Expand Down
6 changes: 3 additions & 3 deletions docs/zh/reference/node-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ interface MarkdownLink {
- [Frontmatter > permalinkPattern](./frontmatter.md#permalinkpattern)


### routeMeta
### meta

- 类型: `Record<string, unknown>`

Expand All @@ -609,11 +609,11 @@ interface MarkdownLink {
附加到 vue-router 路由记录上的额外数据。

- 参考:
- [Frontmatter > routeMeta](./frontmatter.md#routemeta)
- [Frontmatter > meta](./frontmatter.md#meta)
- [vue-router > API 参考 > RouteRecordRaw > meta](https://router.vuejs.org/zh/api/#meta)

::: tip Route Meta 和 Page Data 的区别是什么?
[Route Meta](#routemeta) 和 [Page Data](#data) 都可以在客户端代码中使用。然而, Route Meta 是附加在路由记录上的,因此当用户进入你的站点时,所有页面的 Route Meta 都会立即被加载。相比之下, Page Data 是存储在单独的文件中的,只有在用户进入对应页面时才会被加载。
[Route Meta](#meta) 和 [Page Data](#data) 都可以在客户端代码中使用。然而, Route Meta 是附加在路由记录上的,因此当用户进入你的站点时,所有页面的 Route Meta 都会立即被加载。相比之下, Page Data 是存储在单独的文件中的,只有在用户进入对应页面时才会被加载。

因此,不建议在 Route Meta 中存储大量的信息,否则在站点有很多页面时,将会影响站点的初始加载速度。
:::
Expand Down
4 changes: 2 additions & 2 deletions docs/zh/reference/plugin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export default {

该 Hook 可以用来在 Page 对象上添加额外的属性,或修改现有的属性等。

值得一提的是,针对 `page.data` 和 `page.routeMeta` 的改动可以在客户端代码中使用。
值得一提的是,针对 `page.data` 和 `page.meta` 的改动可以在客户端代码中使用。

- 示例:

Expand Down Expand Up @@ -325,7 +325,7 @@ export default {
- 参考:
- [客户端 API > usePageData](./client-api.md#usepagedata)
- [Node API > Page 属性 > data](./node-api.md#data)
- [Node API > Page 属性 > routeMeta](./node-api.md#routemeta)
- [Node API > Page 属性 > meta](./node-api.md#meta)

## 生命周期 Hooks

Expand Down
20 changes: 6 additions & 14 deletions ecosystem/theme-default/src/client/composables/useNavLink.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { resolve } from '@vuepress/client'
import type { NavLink } from '../../shared/index.js'
import { useResolveRouteWithRedirect } from './useResolveRouteWithRedirect.js'

declare module 'vue-router' {
interface RouteMeta {
title?: string
}
}

/**
* Resolve NavLink props from string
Expand All @@ -14,13 +8,11 @@ declare module 'vue-router' {
* - Input: '/README.md'
* - Output: { text: 'Home', link: '/' }
*/
export const useNavLink = (item: string): NavLink => {
// the route path of vue-router is url-encoded, and we expect users are using
// non-url-encoded string in theme config, so we need to url-encode it first to
// resolve the route correctly
const resolved = useResolveRouteWithRedirect(encodeURI(item))
export const useNavLink = (path: string): NavLink => {
const { path: link, meta } = resolve<{ title: string }>(path)

return {
text: resolved.meta.title || item,
link: resolved.name === '404' ? item : resolved.fullPath,
text: meta?.title || link,
link,
}
}
2 changes: 1 addition & 1 deletion ecosystem/theme-default/src/node/defaultTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const defaultTheme = ({
// save relative file path into page data to generate edit link
page.data.filePathRelative = page.filePathRelative
// save title into route meta to generate navbar and sidebar
page.routeMeta.title = page.title
page.meta.title = page.title
},

plugins: [
Expand Down
8 changes: 2 additions & 6 deletions packages/cli/src/commands/dev/handlePageAdd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import {
createPage,
preparePageComponent,
preparePageData,
preparePagesComponents,
preparePagesData,
preparePagesRoutes,
preparePagesMap,
} from '@vuepress/core'
import type { App, Page } from '@vuepress/core'

Expand Down Expand Up @@ -36,9 +34,7 @@ export const handlePageAdd = async (
await preparePageData(app, page)

// prepare pages entry
await preparePagesComponents(app)
await preparePagesData(app)
await preparePagesRoutes(app)
await preparePagesMap(app)

return page
}
20 changes: 6 additions & 14 deletions packages/cli/src/commands/dev/handlePageChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import {
createPage,
preparePageComponent,
preparePageData,
preparePagesComponents,
preparePagesData,
preparePagesRoutes,
preparePagesMap,
} from '@vuepress/core'
import type { App, Page } from '@vuepress/core'

Expand Down Expand Up @@ -39,18 +37,12 @@ export const handlePageChange = async (
await preparePageData(app, pageNew)

const isPathChanged = pageOld.path !== pageNew.path
const isRouteMetaChanged =
JSON.stringify(pageOld.routeMeta) !== JSON.stringify(pageNew.routeMeta)
const isMetaChanged =
JSON.stringify(pageOld.meta) !== JSON.stringify(pageNew.meta)

// prepare pages entry if the path is changed
if (isPathChanged) {
await preparePagesComponents(app)
await preparePagesData(app)
}

// prepare pages routes if the path or routeMeta is changed
if (isPathChanged || isRouteMetaChanged) {
await preparePagesRoutes(app)
// prepare pages map if the path or meta is changed
if (isPathChanged || isMetaChanged) {
await preparePagesMap(app)
}

return [pageOld, pageNew]
Expand Down
10 changes: 2 additions & 8 deletions packages/cli/src/commands/dev/handlePageUnlink.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
preparePagesComponents,
preparePagesData,
preparePagesRoutes,
} from '@vuepress/core'
import { preparePagesMap } from '@vuepress/core'
import type { App, Page } from '@vuepress/core'

/**
Expand All @@ -26,9 +22,7 @@ export const handlePageUnlink = async (
app.pages.splice(pageIndex, 1)

// re-prepare page files
await preparePagesComponents(app)
await preparePagesData(app)
await preparePagesRoutes(app)
await preparePagesMap(app)

return page
}
4 changes: 1 addition & 3 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@
"external": [
"@internal/clientConfigs",
"@internal/layoutComponents",
"@internal/pagesComponents",
"@internal/pagesData",
"@internal/pagesRoutes",
"@internal/pagesMap",
"@internal/siteData"
],
"format": [
Expand Down
7 changes: 3 additions & 4 deletions packages/client/src/components/Content.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { pagesComponents } from '@internal/pagesComponents'
import { computed, defineComponent, h } from 'vue'
import { usePageData } from '../composables/index.js'
import { pagesMap, usePageData } from '../composables/index.js'

/**
* Markdown rendered content
Expand All @@ -10,7 +9,7 @@ export const Content = defineComponent({
name: 'Content',

props: {
pageKey: {
url: {
type: String,
required: false,
default: '',
Expand All @@ -20,7 +19,7 @@ export const Content = defineComponent({
setup(props) {
const page = usePageData()
const pageComponent = computed(
() => pagesComponents[props.pageKey || page.value.key],
() => pagesMap.value.get(props.url || page.value.path)?.comp,
)
return () =>
pageComponent.value
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export * from './pageHead.js'
export * from './pageHeadTitle.js'
export * from './pageLang.js'
export * from './pageLayout.js'
export * from './pagesData.js'
export * from './pagesMap.js'
export * from './routeLocale.js'
export * from './siteData.js'
export * from './siteLocaleData.js'
Expand Down
27 changes: 0 additions & 27 deletions packages/client/src/composables/pagesData.ts

This file was deleted.

26 changes: 26 additions & 0 deletions packages/client/src/composables/pagesMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { pagesMap as pagesMapRaw } from '@internal/pagesMap'
import type { PagesMap } from '@internal/pagesMap'
import { ref } from 'vue'
import type { Ref } from 'vue'

/**
* Ref wrapper of `PagesMap`
*/
export type PagesMapRef = Ref<PagesMap>

/**
* Global pages map ref
*/
export const pagesMap: PagesMapRef = ref(pagesMapRaw)

/**
* Returns the ref of pages map
*/
export const usePagesMap = (): PagesMapRef => pagesMap

if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) {
// reuse vue HMR runtime
__VUE_HMR_RUNTIME__.updatePagesMap = (data: PagesMap) => {
pagesMap.value = data
}
}
1 change: 1 addition & 0 deletions packages/client/src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './defineClientConfig.js'
export * from './router.js'
export * from './withBase.js'
Loading