Render
实时解析 Markdown 文本并渲染为安全、美观的 HTML 内容。
基础用法
通过 src 传入 Markdown 字符串,渲染对应的 HTML 内容。
展开源代码
<template>
<vmd-render :src="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>解析 HTML 标签
使用 html 可以控制是否解析 Markdown 中的 HTML 标签。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="html" name="checkbox" type="checkbox" />
启用 html
</label>
</p>
<vmd-render :src="md" :html="html" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const html = ref(true)
const md = `
# Lorem ipsum
<p style="background: rgba(9, 105, 218, 0.14); padding: 10px">
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.
</p>
`
</script>HTML 标签安全过滤
使用 sanitize 可以对生成结果中的 HTML 标签进行安全过滤,以预防 XSS 等网络攻击。开启 sanitize 可能会影响 HTML 标签的生成效果,如果最终结果不符合预期且您对安全性要求较低,可以尝试关闭 sanitize 选项,但请注意这是非常危险的行为。如果您对安全性要求比较高,建议直接关闭 html 选项。
展开源代码
<template>
<div>
<h4>markdown 文本:</h4>
<pre style="background: #fff; overflow: auto"><code>{{ md }}</code></pre>
<h4>渲染结果:</h4>
<vmd-render :src="md" />
</div>
</template>
<script setup>
const md = `
<p style="background: rgba(9, 105, 218, 0.14); padding: 10px">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<iframe//src=jAva	script:alert(3)>def
</p>
`
</script>常用预设规则
使用 preset-name 可以快捷地设置 Markdown 语法规则。内置三种常用预设: default(默认预设,类似 GFM),commonmark(详情请看)和 zero(所有语法规则都不会启用)。
提示
和 markdown-it 的 default 预设规则稍有不同,这里的 html 选项默认是开启的。
展开源代码
<template>
<div>
<p>
<label>
请选择预设规则:
<select v-model="presetName" name="select">
<option v-for="item in options" :key="item" :value="item">{{ item }}</option>
</select>
</label>
</p>
<template v-for="item in options" :key="item">
<vmd-render v-if="item === presetName" :src="md" :preset-name="item" />
</template>
</div>
</template>
<script setup>
import { ref } from 'vue'
const options = ['default', 'commonmark', 'zero']
const presetName = ref('default')
const md = `
| 预设名称 | 说明 |
| ----------------------------------------------------------------------------------------------- | ----------------------------------- |
| [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.mjs) | 默认预设,类似 GFM |
| [commonmark](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.mjs) | 详情[请看](https://commonmark.org/) |
| [zero](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.mjs) | 所有语法规则都不会启用 |
`
</script>markdown-it 插件
通过 plugins 可以传入 markdown-it 插件。支持两种传参方式:第一种是直接传入单个插件。第二种可通过数组传入多个插件,数组中的每一项可以是单个插件,也可以是插件和参数组成的数组(如:[插件, [插件, 参数1, 参数2, ...], ...])。
展开源代码
<template>
<vmd-render :src="md" :plugins="plugins" />
</template>
<script setup>
// npm i markdown-it-container
import container from 'markdown-it-container'
const md = `
# Lorem ipsum
::: example
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.
:::
`
const plugins = [
[
container,
'example',
{
render: (tokens, idx) => {
return tokens[idx].nesting === 1 ? '<details><summary>展开内容</summary>\n' : '</details>\n'
}
}
]
]
</script>单行模式
使用 inline 时会跳过块级元素的解析,并且生成结果不会被包裹到 <p> 标签中。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="inline" name="checkbox" type="checkbox" />
启用 inline
</label>
</p>
<vmd-render :src="md" :inline="inline" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const inline = ref(true)
const md = `
# Lorem ipsum
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>XHTML 输出
使用 xhtml-out 可以使生成结果符合 XHTML 标准。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="xhtmlOut" name="checkbox" type="checkbox" />
启用 xhtml-out
</label>
</p>
<h4>解析结果:</h4>
<div style="background: #fff; padding: 32px">
{{ renderRef?.htmlStr }}
</div>
<h4>渲染结果:</h4>
<vmd-render ref="renderRef" :src="md" :xhtml-out="xhtmlOut" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const xhtmlOut = ref(true)
const md = `
---
`
</script>换行处理
使用 breaks 可以将 Markdown 文本中的 \n 解析为 <br> 标签。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="breaks" name="checkbox" type="checkbox" />
启用 breaks
</label>
</p>
<h4>解析结果:</h4>
<div style="background: #fff; padding: 32px">
{{ renderRef?.htmlStr }}
</div>
<h4>渲染结果:</h4>
<vmd-render ref="renderRef" :src="md" :breaks="breaks" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const renderRef = ref(null)
const breaks = ref(true)
const md = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nMorbi maximus elit fermentum pellentesque vehicula.
`
</script>代码块语法高亮
使用 highlight 可以将 Markdown 中的代码块根据其编程语言进行语法高亮。当传入布尔值时,会使用 highlight.js 作为语法高亮工具,此时您可以通过 highlight-options 来配置它,详细配置项请参考。当默认语法高亮无法满足需求时,highlight 也支持通过函数来自定义高亮语法规则。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="highlight" name="checkbox" type="checkbox" />
启用 highlight
</label>
</p>
<h4>布尔值:</h4>
<vmd-render :src="md" :highlight="highlight" />
<h4>函数:</h4>
<vmd-render :src="md" :highlight="highlight && customHighlight" />
</div>
</template>
<script setup>
// npm i highlight.js
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import { ref } from 'vue'
const highlight = ref(true)
const customHighlight = (str, language) => {
return hljs.highlight(str, { language }).value
}
const md = `
\`\`\` js
var foo = function (bar) {
return bar++;
};
console.log(foo(5));
\`\`\`
`
</script>自定义语法高亮样式
通过 lang-prefix 修改代码块样式名前缀来自定义语法高亮样式。
展开源代码
<template>
<div>
<p>
<label>
请选择类名前缀:
<select v-model="langPrefix" name="select">
<option value="custom-">自定义类名前缀 custom-</option>
<option value="language-">默认类名前缀 language-</option>
</select>
</label>
</p>
<vmd-render :src="md" :lang-prefix="langPrefix" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const langPrefix = ref('custom-')
const md = `
\`\`\` js
var foo = function (bar) {
return bar++;
};
console.log(foo(5));
\`\`\`
`
</script>
<style>
.custom-js {
color: #666666 !important;
}
.custom-js .hljs-keyword {
color: #ab5959 !important;
}
.custom-js .hljs-title {
color: #59873a !important;
}
.custom-js .hljs-variable,
.custom-js .hljs-params {
color: #b07d48 !important;
}
.custom-js .hljs-string {
color: #b56959 !important;
}
</style>自动转换链接
使用 linkify 可以将 Markdown 中类似 url 的文本转换为链接。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="linkify" name="checkbox" type="checkbox" />
启用 linkify
</label>
</p>
<vmd-render :src="md" :linkify="linkify" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const linkify = ref(true)
const md = `
链接:[https://www.example.com](https://www.example.com)
类似 url 的文本:https://www.example.com
`
</script>常见符号处理
使用 typographer 可以将 Markdown 中的一些特定文本替换为常见的符号。当 typographer 开启时,还可以通过 quotes 自定义引号,这在多语言环境中非常实用。
展开源代码
<template>
<div>
<p>
<label>
<input v-model="typographer" name="checkbox" type="checkbox" />
启用 typographer
</label>
</p>
<p>
<label>
请输入引号:
<input
v-for="(item, index) in quotes"
:key="item"
v-model="quotes[index]"
name="text"
style="width: 2em; margin: 4px"
/>
</label>
</p>
<vmd-render :src="md" :typographer="typographer" :quotes="[...quotes]" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const typographer = ref(true)
const quotes = ref(['«', '»', '‹', '›'])
const md = `
版权符号:(c)
注册中商标:(tm)
注册商标:(r)
"这是一个双引号示例"
'这是一个单引号示例'
`
</script>Emoji 表情
通过 emoji 可以将 Markdown 中的特定文本解析为 Emoji 表情。除了支持布尔值传参外,还可以通过传入对象来配置 Emoji 表情,详细配置请参考。
展开源代码
<template>
<vmd-render :src="md" :emoji="emoji" />
</template>
<script setup>
const emoji = {
shortcuts: {
smiley: ':-)',
frowning: ':-(',
sunglasses: '8-)',
wink: ';)'
}
}
const md = `
经典表情: :wink: :cry: :laughing: :yum:
自定义符号::-) :-( 8-) ;)
`
</script>标题锚点
通过 anchor 可以为所有标题元素添加唯一标识符(ID),这可以帮助导航组件(如 Toc 组件)实现锚点定位。当开启 anchor 时会默认在所有标题前面添加永久链接,您可以通过 permalink 控制它的显示隐藏。anchor 还支持传入对象或函数来自定义标题的渲染,更多配置项请参考。
展开源代码
<template>
<div>
<h4>默认标题渲染:</h4>
<p>
<label>
<input v-model="permalink" name="checkbox" type="checkbox" />
启用 permalink(鼠标悬浮在标题上可显示永久链接符号)
</label>
</p>
<vmd-render :src="md" :permalink="permalink" />
<h4>自定义标题渲染:</h4>
<vmd-render :src="md" :anchor="anchorOptions" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const permalink = ref(true)
const anchorOptions = (anchor) => ({
permalink: anchor.permalink.headerLink()
})
const md = `
# Lorem ipsum
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>自定义样式
默认使用 github-markdown-css 作为渲染结果的样式,也可以通过 markdown-class 来自定义您的样式。
展开源代码
<template>
<div>
<p>
<label>
请选择样式名:
<select v-model="markdownClass" name="select">
<option value="custom-theme">自定义样式 custom-theme</option>
<option value="markdown-body">默认样式 markdown-body</option>
<option value="">无样式</option>
</select>
</label>
</p>
<vmd-render :src="md" :markdown-class="markdownClass" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const markdownClass = ref('custom-theme')
const md = `
# Lorem ipsum
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>
<style>
.custom-theme {
background: #fffffd;
}
.custom-theme * {
margin: 0;
}
.custom-theme h1 {
font-size: 2.4em;
padding-bottom: 0.3em;
border-bottom: 3px double #eee;
margin-bottom: 0.6em;
line-height: 1.35;
font-weight: bolder;
color: #456688;
}
.custom-theme p {
margin-bottom: 1.2em;
color: #383838;
}
.custom-theme a {
color: #456688;
text-decoration: none;
}
</style>API
Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| src | Markdown 字符串 | string / number | '' |
| html | 是否解析 Markdown 中的 HTML 标签 | boolean | true |
| sanitize | 是否对生成结果中的 HTML 标签进行安全过滤。支持布尔值或者 DOMPurify 配置 | boolean / SanitizeOptions | true |
| preset-name | Markdown 预设规则 | 'default' | 'commonmark' | 'zero' | default |
| plugins | markdown-it 插件 | PluginSimple / Array<PluginSimple | [PluginWithParams, ...any[]]> | [] |
| inline | 是否启用单行模式 | boolean | false |
| xhtml-out | 是否生成符合 XHTML 标准的结果 | boolean | false |
| breaks | 是否将 \n 解析为 <br> 标签 | boolean | false |
| highlight | 是否启用代码块语法高亮 | boolean / (str: string, lang: string, attrs: string) => string | true |
| highlight-options | 代码块语法高亮配置,仅在 highlight 为 true 时生效。详情请参考 highlight.js 配置 | HLJSOptions | - |
| lang-prefix | 代码块样式名前缀 | string | language- |
| linkify | 是否将类似 url 的文本转换为链接 | boolean | false |
| typographer | 是否将特定文本替换为常见的符号 | boolean | false |
| quotes | 自定义引号,仅在 typographer 开启时生效 | string / Array<string> | “”‘’ |
| emoji | 是否将特定文本解析为 Emoji 表情。支持布尔值或者 markdown-it-emoji 配置 | boolean / EmojiOptions | true |
| anchor | 标题渲染配置。支持布尔值、markdown-it-anchor 配置或函数 | boolean / AnchorOptions / (anchor: Anchor) => AnchorOptions | true |
| permalink | 是否开启标题永久链接,仅在 anchor 为 true 时生效 | boolean | true |
| markdown-class | 自定义 markdown 样式名 | string | markdown-body |
事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| env-change | 当 markdown-it 中的 env 变化时触发 | value: {} |
方法
| 方法名 | 说明 | 类型 |
|---|---|---|
| mdInstance | 获取组件内部 markdown-it 实例 | MarkdownIt |
| htmlStr | 获取解析结果的字符串 | string |