Skip to content

Commit 0ea1720

Browse files
committed
feat(plugin-toc): add toc plugin
1 parent 8f3aab1 commit 0ea1720

File tree

16 files changed

+580
-0
lines changed

16 files changed

+580
-0
lines changed

docs/.vuepress/configs/sidebar/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export const en: SidebarConfig = {
109109
'/reference/plugin/git.md',
110110
'/reference/plugin/palette.md',
111111
'/reference/plugin/theme-data.md',
112+
'/reference/plugin/toc.md',
112113
],
113114
},
114115
],

docs/.vuepress/configs/sidebar/zh.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export const zh: SidebarConfig = {
112112
'/zh/reference/plugin/git.md',
113113
'/zh/reference/plugin/palette.md',
114114
'/zh/reference/plugin/theme-data.md',
115+
'/zh/reference/plugin/toc.md',
115116
],
116117
},
117118
],

docs/reference/plugin/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
- [git](./git.md)
2020
- [palette](./palette.md)
2121
- [theme-data](./theme-data.md)
22+
- [toc](./toc.md)

docs/reference/plugin/toc.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# toc
2+
3+
> [@vuepress/plugin-toc](https://www.npmjs.com/package/@vuepress/plugin-toc)
4+
5+
This plugin will provide a table-of-contents (TOC) component.
6+
7+
## Differences with Markdown TOC Syntax
8+
9+
Similar to the [Table of Contents Markdown Syntax](../../guide/markdown.md#table-of-contents), the TOC component that provided by this plugin could be used in your markdown content directly:
10+
11+
```md
12+
<!-- markdown toc syntax -->
13+
[[toc]]
14+
15+
<!-- vue toc component -->
16+
<Toc />
17+
```
18+
19+
Both of them can be pre-rendered correctly in build mode. However, there are some differences between them.
20+
21+
The markdown syntax `[[toc]]` could only be used in markdown files. It is parsed by markdown-it, and the generated TOC is static content.
22+
23+
The component `<Toc/>` could be used in both markdown files and vue files. It is loaded by vue, and the generated TOC is a vue component.
24+
25+
This plugin could work together with [@vuepress/plugin-active-header-links](./active-header-links.md) by setting the [headerLinkSelector](./active-header-links.md#headerlinkselector) to match the `linkClass` option. When the page scroll to a certain header anchor, this corresponding link will be added `linkActiveClass` class name.
26+
27+
Therefore, this plugin is more useful for theme developers.
28+
29+
## Options
30+
31+
### componentName
32+
33+
- Type: `string`
34+
35+
- Default: `Toc`
36+
37+
- Details:
38+
39+
Specify the name of the TOC component.
40+
41+
### defaultPropsOptions
42+
43+
- Type: `Partial<TocPropsOptions>`
44+
45+
- Default: `{}`
46+
47+
- Details:
48+
49+
Override the default values of the component [options](#options-1) prop.
50+
51+
## Component Props
52+
53+
The TOC component also accepts props for customization.
54+
55+
```vue
56+
<template>
57+
<Toc :headers="headers" :options="options" />
58+
</template>
59+
```
60+
61+
### headers
62+
63+
- Type: `PageHeader[]`
64+
65+
```ts
66+
interface PageHeader {
67+
level: number
68+
title: string
69+
slug: string
70+
children: PageHeader[]
71+
}
72+
```
73+
74+
- Details:
75+
76+
Specify the headers array to render.
77+
78+
If this prop is not specified, the headers of current page will be used.
79+
80+
### options
81+
82+
- Type: `Partial<TocPropsOptions>`
83+
84+
```ts
85+
interface TocPropsOptions {
86+
containerTag: string
87+
containerClass: string
88+
listClass: string
89+
itemClass: string
90+
linkTag: 'a' | 'RouterLink'
91+
linkClass: string
92+
linkActiveClass: string
93+
linkChildrenActiveClass: string
94+
}
95+
```
96+
97+
- Default:
98+
99+
Following default values can be overridden by [defaultPropsOptions](#defaultpropsoptions).
100+
101+
```ts
102+
const defaultOptions = {
103+
containerTag: 'nav',
104+
containerClass: 'vuepress-toc',
105+
listClass: 'vuepress-toc-list',
106+
itemClass: 'vuepress-toc-item',
107+
linkTag: 'RouterLink',
108+
linkClass: 'vuepress-toc-link',
109+
linkActiveClass: 'active',
110+
linkChildrenActiveClass: 'active',
111+
}
112+
```
113+
114+
- Details:
115+
116+
Customize the TOC component.
117+
118+
If the `containerTag` is set to an empty string `''`, the `<nav>` container will be removed totally.
119+
120+
- Example:
121+
122+
The rendered TOC component with default options looks like:
123+
124+
```vue
125+
<template>
126+
<!-- container -->
127+
<nav class="vuepress-toc">
128+
<!-- list -->
129+
<ul class="vuepress-toc-list">
130+
<!-- item -->
131+
<li class="vuepress-toc-item">
132+
<!-- link -->
133+
<RouterLink class="vuepress-toc-link" to="#foo">Foo</RouterLink>
134+
</li>
135+
<!-- item with children -->
136+
<li class="vuepress-toc-item">
137+
<!-- link (children active) -->
138+
<RouterLink class="vuepress-toc-link active" to="#bar">Bar</RouterLink>
139+
<!-- list (children) -->
140+
<ul class="vuepress-toc-list">
141+
<!-- item -->
142+
<li class="vuepress-toc-item">
143+
<!-- link (active) -->
144+
<RouterLink class="vuepress-toc-link active" to="#bar-child">Bar Child</RouterLink>
145+
</li>
146+
</ul>
147+
</li>
148+
</ul>
149+
</nav>
150+
</template>
151+
```

docs/zh/reference/plugin/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
- [git](./git.md)
2020
- [palette](./palette.md)
2121
- [theme-data](./theme-data.md)
22+
- [toc](./toc.md)

docs/zh/reference/plugin/toc.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# toc
2+
3+
> [@vuepress/plugin-toc](https://www.npmjs.com/package/@vuepress/plugin-toc)
4+
5+
该插件会提供一个目录 (table-of-contents, TOC) 组件。
6+
7+
## 与 Markdown 目录语法的区别
8+
9+
[Markdown 目录语法](../../guide/markdown.md#目录) 类似,该插件提供的目录组件可以直接在你的 Markdown 内容中使用:
10+
11+
```md
12+
<!-- Markdown 目录语法 -->
13+
[[toc]]
14+
15+
<!-- Vue 目录组件 -->
16+
<Toc />
17+
```
18+
19+
在 Build 模式中,它们都可以被正确地预渲染。然而,它们之间存在一些区别。
20+
21+
Markdown 语法 `[[toc]]` 仅能在 Markdown 文件中使用。它是由 markdown-it 解析的,生成的目录是静态内容。
22+
23+
组件 `<Toc/>` 既可以用在 Markdown 文件中,也可以用在 Vue 文件中。它是由 Vue 加载的,生成的目录是一个 Vue 组件。
24+
25+
该插件可以和 [@vuepress/plugin-active-header-links](./active-header-links.md) 协同工作,你只需要将 [headerLinkSelector](./active-header-links.md#headerlinkselector) 与该插件的 `linkClass` 匹配即可。当页面滚动至某个标题锚点后,对应的链接就会被加上 `linkActiveClass` 类名。
26+
27+
因此,该插件对于主题开发者来说更为有用。
28+
29+
## 配置项
30+
31+
### componentName
32+
33+
- 类型: `string`
34+
35+
- 默认值: `Toc`
36+
37+
- 详情:
38+
39+
指定目录组件的名称。
40+
41+
### defaultPropsOptions
42+
43+
- 类型: `Partial<TocPropsOptions>`
44+
45+
- 默认值: `{}`
46+
47+
- 详情:
48+
49+
覆盖组件 [options](#options) Prop 的默认值。
50+
51+
## 组件 Props
52+
53+
目录组件可以通过 Props 来进行自定义。
54+
55+
```vue
56+
<template>
57+
<Toc :headers="headers" :options="options" />
58+
</template>
59+
```
60+
61+
### headers
62+
63+
- 类型: `PageHeader[]`
64+
65+
```ts
66+
interface PageHeader {
67+
level: number
68+
title: string
69+
slug: string
70+
children: PageHeader[]
71+
}
72+
```
73+
74+
- 详情:
75+
76+
指定要渲染的标题数组。
77+
78+
如果该 Prop 没有被设置,默认会使用当前页面的标题。
79+
80+
### options
81+
82+
- 类型: `Partial<TocPropsOptions>`
83+
84+
```ts
85+
interface TocPropsOptions {
86+
containerTag: string
87+
containerClass: string
88+
listClass: string
89+
itemClass: string
90+
linkTag: 'a' | 'RouterLink'
91+
linkClass: string
92+
linkActiveClass: string
93+
linkChildrenActiveClass: string
94+
}
95+
```
96+
97+
- 默认值:
98+
99+
下列默认值可以用过 [defaultPropsOptions](#defaultpropsoptions) 来覆盖:
100+
101+
```ts
102+
const defaultOptions = {
103+
containerTag: 'nav',
104+
containerClass: 'vuepress-toc',
105+
listClass: 'vuepress-toc-list',
106+
itemClass: 'vuepress-toc-item',
107+
linkTag: 'RouterLink',
108+
linkClass: 'vuepress-toc-link',
109+
linkActiveClass: 'active',
110+
linkChildrenActiveClass: 'active',
111+
}
112+
```
113+
114+
- 详情:
115+
116+
自定义目录组件。
117+
118+
如果 `containerTag` 设置为空字符串 `''` ,那么最外层的 `<nav>` Container 会被完全移除。
119+
120+
- 示例:
121+
122+
使用默认 options 的目录组件的渲染结果类似以下结构:
123+
124+
```vue
125+
<template>
126+
<!-- container -->
127+
<nav class="vuepress-toc">
128+
<!-- list -->
129+
<ul class="vuepress-toc-list">
130+
<!-- item -->
131+
<li class="vuepress-toc-item">
132+
<!-- link -->
133+
<RouterLink class="vuepress-toc-link" to="#foo">Foo</RouterLink>
134+
</li>
135+
<!-- item with children -->
136+
<li class="vuepress-toc-item">
137+
<!-- link (children active) -->
138+
<RouterLink class="vuepress-toc-link active" to="#bar">Bar</RouterLink>
139+
<!-- list (children) -->
140+
<ul class="vuepress-toc-list">
141+
<!-- item -->
142+
<li class="vuepress-toc-item">
143+
<!-- link (active) -->
144+
<RouterLink class="vuepress-toc-link active" to="#bar-child">Bar Child</RouterLink>
145+
</li>
146+
</ul>
147+
</li>
148+
</ul>
149+
</nav>
150+
</template>
151+
```
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "@vuepress/plugin-toc",
3+
"version": "2.0.0-beta.6",
4+
"description": "VuePress plugin - toc",
5+
"keywords": [
6+
"vuepress-plugin",
7+
"vuepress",
8+
"plugin",
9+
"toc"
10+
],
11+
"homepage": "https://github.com/vuepress",
12+
"bugs": {
13+
"url": "https://github.com/vuepress/vuepress-next/issues"
14+
},
15+
"repository": {
16+
"type": "git",
17+
"url": "git+https://github.com/vuepress/vuepress-next.git"
18+
},
19+
"license": "MIT",
20+
"author": "meteorlxy",
21+
"main": "lib/index.js",
22+
"types": "lib/index.d.ts",
23+
"files": [
24+
"lib"
25+
],
26+
"scripts": {
27+
"build": "tsc -b tsconfig.build.json",
28+
"clean": "rimraf lib *.tsbuildinfo"
29+
},
30+
"dependencies": {
31+
"@vuepress/client": "2.0.0-beta.6",
32+
"@vuepress/core": "2.0.0-beta.6",
33+
"@vuepress/utils": "2.0.0-beta.5",
34+
"vue": "^3.0.11"
35+
},
36+
"publishConfig": {
37+
"access": "public"
38+
}
39+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { h } from 'vue'
2+
import { defineClientAppEnhance } from '@vuepress/client'
3+
import { Toc } from './components/Toc'
4+
import type { TocPropsOptions } from './types'
5+
6+
declare const TOC_COMPONENT_NAME: string
7+
declare const TOC_DEFAULT_PROPS_OPTIONS: TocPropsOptions
8+
9+
export default defineClientAppEnhance(({ app }) => {
10+
// wrap the component with default options
11+
app.component(TOC_COMPONENT_NAME, (props) =>
12+
h(Toc, {
13+
headers: props.headers,
14+
options: {
15+
...TOC_DEFAULT_PROPS_OPTIONS,
16+
...props.options,
17+
},
18+
})
19+
)
20+
})

0 commit comments

Comments
 (0)