Toc
Generates a table of contents for the rendered Markdown.
Basic Usage
Use target to specify the element to generate the TOC. It supports CSS selector, DOM element, component instance, or a function that returns any of these. The default is document.documentElement.
View Source
<template>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Plain Text
Use plain-text to generate a plain-text TOC. In this mode, clicking items will not trigger anchor scrolling.
View Source
<template>
<div>
<p>
<label>
<input v-model="plainText" name="checkbox" type="checkbox" />
Enable plain-text
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" :plain-text="plainText" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const plainText = ref(true)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Use Markdown Directly
Use markdown to generate a plain-text TOC directly from Markdown. If both target and markdown are provided, target takes precedence.
View Source
<template>
<vmd-toc :markdown="md" />
</template>
<script setup>
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Ordered List
Use ordered-list to generate an ordered TOC.
View Source
<template>
<div>
<p>
<label>
<input v-model="orderedList" name="checkbox" type="checkbox" />
Enable ordered-list
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" :ordered-list="orderedList" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const orderedList = ref(true)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Heading Level Range
Use start-level and end-level to control the heading level range used to build the TOC.
View Source
<template>
<div>
<p>
<label>
Select start-level:
<select v-model="startLevel" name="select">
<option v-for="key in options" :key="key" :value="key">h{{ key }}</option>
</select>
</label>
</p>
<p>
<label>
Select end-level:
<select v-model="endLevel" name="select">
<option v-for="key in options" :key="key" :value="key">h{{ key }}</option>
</select>
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc
style="flex: auto"
:target="renderRef"
:start-level="startLevel"
:end-level="endLevel"
/>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const startLevel = ref(2)
const endLevel = ref(5)
const options = Array.from({ length: 6 }, (_, index) => index + 1)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Ignore Headings
Use ignore to ignore specific heading levels when generating the TOC.
View Source
<template>
<div>
<p>
Select heading levels to ignore:
<label v-for="(_, index) in ignoreList" :key="index" style="margin-right: 10px">
<input v-model="ignoreList[index]" name="checkbox" type="checkbox" />
h{{ index + 1 }}
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" :ignore="ignore" />
</div>
</div>
</template>
<script setup>
import { ref, watchEffect } from 'vue'
const renderRef = ref(null)
const ignore = ref([])
const ignoreList = ref([false, false, true, false, false, false])
watchEffect(() => {
ignore.value = ignoreList.value.map((item, index) => Number(item) && index + 1).filter(Boolean)
})
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Empty Text
Use empty-text to customize the text displayed when the TOC is empty.
View Source
<template>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="flex: 70%" :src="md" />
<vmd-toc style="flex: auto" empty-text="Nothing to Show" :target="renderRef" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const md = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi maximus elit fermentum pellentesque vehicula. Suspendisse potenti. Donec iaculis consectetur erat nec placerat. Suspendisse facilisis justo sit amet hendrerit sollicitudin. Suspendisse commodo malesuada massa, ac elementum risus. Ut eu facilisis neque. Fusce tincidunt, ligula vitae eleifend venenatis, purus purus ultrices purus, nec maximus tellus lectus nec leo. Sed auctor magna sed quam dapibus dapibus. Nullam ornare ultricies sem, a iaculis sapien volutpat euismod. Sed ac dictum nulla. Duis euismod tellus vitae diam hendrerit, sit amet vestibulum mauris rhoncus.
`
</script>Scroll Offset
When clicking a TOC item triggers anchor scrolling, you can use offset to adjust the scroll position. It supports numbers and string positions (center, start, end, nearest). When the component is nested inside multiple scroll containers, the scroll behavior and offset only apply to the nearest scroll container.
View Source
<template>
<div>
<h4>Number:</h4>
<div style="display: flex; flex-wrap: wrap">
<div style="flex: 70%; overflow: auto; position: relative">
<div
style="
width: 100%;
background: #0969da;
position: absolute;
top: 0;
color: #fff;
padding: 16px 32px;
box-sizing: border-box;
z-index: 1;
"
>
Fixed header
</div>
<div style="height: 436px; overflow: auto">
<vmd-render ref="basicWhenNumber" style="margin-top: 56px" :src="md" />
</div>
</div>
<vmd-toc style="flex: auto" :offset="56" :target="basicWhenNumber" />
</div>
<h4>String:</h4>
<div style="display: flex; flex-wrap: wrap">
<div style="flex: 70%; overflow: auto; position: relative">
<div
style="
width: 100%;
background: #0969da;
position: absolute;
top: 0;
color: #fff;
padding: 16px 32px;
box-sizing: border-box;
z-index: 1;
"
>
Fixed header
</div>
<div style="height: 436px; overflow: auto">
<vmd-render ref="basicWhenPosition" style="margin-top: 56px" :src="md" />
</div>
</div>
<vmd-toc style="flex: auto" offset="end" :target="basicWhenPosition" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const basicWhenNumber = ref(null)
const basicWhenPosition = ref(null)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Smooth Scrolling
Use smooth to enable smooth scrolling during anchor navigation.
View Source
<template>
<div>
<p>
<label>
<input v-model="smooth" name="checkbox" type="checkbox" />
Enable smooth
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" :smooth="smooth" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const smooth = ref(true)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Update Page Hash
When clicking a TOC item triggers anchor navigation, you can use change-hash to control whether the page hash is updated.
View Source
<template>
<div>
<p>
<label>
<input v-model="changeHash" name="checkbox" type="checkbox" />
Enable change-hash
</label>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef" :change-hash="changeHash" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const changeHash = ref(true)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>Manual Refresh
Use the refresh method to refresh the generated TOC manually.
TIP
If you use a Render component instance as the TOC target, manual refresh is usually unnecessary because Toc automatically refreshes when the content changes.
View Source
<template>
<div>
<p>
<label style="margin-right: 10px">
Select content:
<select v-model="index" name="select">
<option v-for="(item, index) in options" :key="item.title" :value="index">
{{ item.title }}
</option>
</select>
</label>
<button @click="refresh">Update</button>
</p>
<div style="display: flex; flex-wrap: wrap">
<vmd-render id="refreshRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc ref="tocRef" target="#refreshRef" style="flex: auto" />
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const options = [
{
title: 'Lorem',
value:
'# Lorem\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi maximus elit fermentum pellentesque vehicula. Suspendisse potenti. Donec iaculis consectetur erat nec placerat. Suspendisse facilisis justo sit amet hendrerit sollicitudin. Suspendisse commodo malesuada massa, ac elementum risus. Ut eu facilisis neque. Fusce tincidunt, ligula vitae eleifend venenatis, purus purus ultrices purus, nec maximus tellus lectus nec leo. Sed auctor magna sed quam dapibus dapibus. Nullam ornare ultricies sem, a iaculis sapien volutpat euismod. Sed ac dictum nulla. Duis euismod tellus vitae diam hendrerit, sit amet vestibulum mauris rhoncus.\n# Maecenas\nMaecenas at dolor sodales, fermentum enim vel, sagittis mi. Curabitur hendrerit erat nulla, ac dapibus erat aliquam egestas. Aliquam erat volutpat. Ut laoreet, turpis eget scelerisque consectetur, sapien purus aliquam ipsum, ut elementum augue odio sit amet tortor. Nunc id neque leo. Aliquam congue arcu nunc, at lacinia magna convallis at. Etiam ut consectetur elit, nec laoreet mi. Pellentesque at volutpat arcu. Vestibulum eget metus interdum, fringilla dolor quis, venenatis dui. Sed egestas, nunc convallis sollicitudin efficitur, orci dui sagittis enim, in rhoncus sem arcu ut justo. Donec sed nibh enim. Sed id massa eget nisi tincidunt semper ac ornare orci. Fusce felis mi, sollicitudin at nisi et, lacinia interdum quam. Ut elit est, condimentum nec iaculis a, dignissim feugiat purus.'
},
{
title: 'Sed',
value:
'# Sed\nSed lectus nisl, blandit at volutpat et, lobortis ac urna. Etiam elementum id mauris a ultricies. Suspendisse rhoncus est justo, eu pellentesque turpis elementum quis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque vel dolor orci. Vestibulum rhoncus erat vitae molestie porttitor. Phasellus accumsan risus ut enim mollis, quis feugiat massa auctor. Donec vehicula convallis nisi sit amet dapibus. Integer felis erat, interdum eget erat non, facilisis vulputate augue. Ut sed tortor vitae ante venenatis rhoncus eget id tortor. Etiam molestie luctus ligula sit amet venenatis. Aliquam iaculis tristique sem, vitae convallis mi ultricies nec.\n# Nunc\nNunc vulputate neque sit amet nisi sollicitudin, vel luctus justo vehicula. In sed sapien vel tortor interdum ornare quis ac massa. Proin sapien leo, pretium nec tempus sed, fermentum in felis. Praesent viverra velit arcu, pretium ultricies ipsum viverra non. Cras malesuada cursus velit a tincidunt. Nullam pellentesque nunc mi, sed placerat mi pretium quis. Proin laoreet urna sed urna placerat convallis. Integer eget blandit augue. Etiam eget nisi nibh. Maecenas vel nunc non ipsum ultricies facilisis et id augue. Nullam rhoncus tristique rhoncus. Vivamus aliquet elit vitae dui consequat commodo. Aenean maximus velit sed pharetra fringilla. Aenean semper nunc eu massa lobortis, eu aliquam ante rhoncus.'
}
]
const index = ref(0)
const md = ref(options[0].value)
const tocRef = ref(null)
const refresh = () => {
md.value = options[index.value].value
tocRef.value?.refresh()
}
</script>Custom TOC Item
Use the item slot to customize TOC items.
View Source
<template>
<div style="display: flex; flex-wrap: wrap">
<vmd-render ref="renderRef" style="height: 436px; overflow: auto; flex: 70%" :src="md" />
<vmd-toc style="flex: auto" :target="renderRef">
<template #item="tocItem">
<div style="display: flex; justify-content: space-between">
{{ tocItem.text }}
<span v-if="tocItem.isActive">✅</span>
</div>
</template>
</vmd-toc>
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const md = `
# h1 Heading 8-)
## h2 Heading
### h3 Heading
#### h4 Heading
##### h5 Heading
###### h6 Heading
## Horizontal Rules
___
---
***
## Emphasis
**This is bold text**
__This is bold text__
*This is italic text*
_This is italic text_
~~Strikethrough~~
## Blockquotes
> Blockquotes can also be nested...
>> ...by using additional greater-than signs right next to each other...
> > > ...or with spaces between arrows.
## Lists
Unordered
+ Create a list by starting a line with \`+\`, \`-\`, or \`*\`
+ Sub-lists are made by indenting 2 spaces:
- Marker character change forces new list start:
* Ac tristique libero volutpat at
+ Facilisis in pretium nisl aliquet
- Nulla volutpat aliquam velit
+ Very easy!
Ordered
1. Lorem ipsum dolor sit amet
2. Consectetur adipiscing elit
3. Integer molestie lorem at massa
1. You can use sequential numbers...
1. ...or keep all the numbers as \`1.\`
Start numbering with offset:
57. foo
1. bar
## Tables
| Option | Description |
| ------ | ----------- |
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
Right aligned columns
| Option | Description |
| ------:| -----------:|
| data | path to data files to supply the data that will be passed into templates. |
| engine | engine to be used for processing templates. Handlebars is the default. |
| ext | extension to be used for dest files. |
`
</script>API
Props
| Name | Description | Type | Default |
|---|---|---|---|
| target | The target element used to build the TOC | string / HTMLElement / VueInstance / ()=> string | HTMLElement | VueInstance | document.documentElement |
| plain-text | Whether to generate a plain-text TOC | boolean | false |
| markdown | Generate a plain-text TOC from Markdown | string | '' |
| ordered-list | Whether to generate an ordered TOC | boolean | false |
| start-level | Start heading level for the TOC | number / string | 1 |
| end-level | End heading level for the TOC | number / string | 6 |
| ignore | Heading levels to ignore in the TOC | Array<number | string> | [] |
| empty-text | Text displayed when the TOC is empty | string | No Data |
| offset | Scroll offset during TOC anchor navigation | number / 'start'|'end'|'center'|'nearest' | start |
| smooth | Whether to enable smooth scrolling when navigating via the TOC | boolean | false |
| change-hash | Whether to update the page hash when navigating via the TOC | boolean | true |
Events
| Name | Description | Arguments |
|---|---|---|
| click | Triggered when clicking a TOC item. For arguments, see TocItem | tocItem: TocItem |
| change | Triggered when the active TOC item changes | id: string |
Expose
| Name | Description | Type |
|---|---|---|
| scrollTo | Scroll to a given heading in the TOC | (href: string) => void |
| refresh | Regenerate the TOC | () => void |
Slots
| Name | Description | SlotProps |
|---|---|---|
| item | Customize TOC item content. For slot props, see TocItem. | tocItem: TocItem |
TocItem
| Key | Description | Type |
|---|---|---|
| id | Unique ID for the TOC item | string |
| level | Heading level | number |
| relativeLevel | Heading level relative to start-level, always starting at 0 | number |
| text | Text content of the TOC item | string |
| isActive | Whether the item is active | boolean |
| top | Scroll position of the corresponding heading | number |