@ crazydos/vue-马克下架
此软件包提供 Vue 3+ 组件, 以渲染下调的内容 unified 输油管.
并参考自 react-markdown。 。 。 .
特征
- 使用时间 统一 以制成 Markdown (CommonMark)
- QQ 支持渲染额外元素( 如: GFM :
tables, (中文(简体) ),footnotes, (中文(简体) ),task lists页:1 评论 财务报告和审定财务报表 复韵 插件 . - :hammer and wrench:允许为标记下元素定制标记属性. (即:
class, (中文(简体) ),target, (中文(简体) ),rel(例如) - QQ 通过 Vue 启用标记下元素渲染的定制
scoped slot。 。 。 . - ++ 支持减值中的渲染 Vue 组件( 需要)
rehype-raw(中文(简体) ) - * 安全减少标记,以防止有害内容
rehype-sanitize - QQ 与 TypeScript 完全输入, 以便更好的开发者经验和类型安全 .
[TIP] 如果这个包裹对你有所帮助,请随意 帮我买一杯咖啡 ~ (法语)
用于
在线实例和操场
关于更多使用示例和详细的插件配置,请参见: stackblitz 上的用法示例。 。 。 .
移徙:用于 v0.x 用户 :
感谢用户 v0.x 激励我继续这个项目.
现在建议升级为版本 v1.x。没有显著差异 v1.x 财务报告和审定财务报表 v0.x不过 v1.x 已经升级 unified 并增强 TypeScript 支持.
迁移至v1.x,请作以下调整: 1
使用名称导入
v.x : (中文(简体) )
import VueMarkdown from '@crazydos/vue-markdown'
v1.x (韩语)
import { VueMarkdown } from '@crazydos/vue-markdown'
槽前缀
语法 <slot> 标记已更改 .
槽名称现在需要添加前缀 s- 内容如下:
v.x : (中文(简体) )
<!-- in Markdown -->
<slot slot-name="header" />
<!-- Customize in Vue -->
<template #header>
<CusomHeader></CusomHeader>
</header>
v1.x: (中文(简体) )
<!-- in Markdown -->
<slot slot-name="header" />
<!-- Customize in Vue -->
<template #s-header>
<CusomHeader></CusomHeader>
</header>
安装
npm install @crazydos/vue-markdown
统一插件版本
vue-markdown 用途 unified 11。所以请确保您打算使用的统一插件与 unified 11。 。 。 .
以下是插件推荐的版本 :
rehype-raw数字 :^7.0.0remark-gfm数字 :^4.0.0remark-math数字 :^6.0.0rehype-katex数字 :^7.0.1remark-toc数字 :^9.0.0- .
使用量
基础
您可以通过 markdown 道具 (英语).
<script setup lang="ts">
import { VueMarkdown } from '@crazydos/vue-markdown'
import { ref } from 'vue'
const markdown = ref('## Hello World')
</script>
<template>
<VueMarkdown :markdown="markdown" />
</template>
添加统一插件
vue-markdown 通过 unified 插件 。 插入一个 unified 插件,您可以使用相应的选项. vue-markdown 也导出帮助类型来支持此操作 .
<script setup lang="ts">
import { type PluggableList, VueMarkdown } from '@crazydos/vue-markdown'
import { ref } from 'vue'
const markdown = ref(`...`)
const remarkPlugins: PluggableList = [
// ...
]
const rehypePlugins: PluggableList = [
// ...
]
</script>
<template>
<!-- Example 1 -->
<VueMarkdown
:markdown="markdown"
:remark-plugins="remarkPlugins"
:rehype-plugins="rehypePlugins"
/>
<!-- Example 2: Directly add plugins -->
<VueMarkdown
:markdown="markdown"
:remark-plugins="[
// ...
]"
:rehype-plugins="[
// ...
]"
/>
</template>
渲染 GFM
默认, vue-markdown 只支持基本的Markdown语法(CommonMark). 如果您需要支持其他 Markdown 语法, 您需要插入相应的语法 unified 插件 .
对于像 tables, (中文(简体) ), footnotes, (中文(简体) ), task lists等,您需要包含 remark-gfm 插件 。 (如果像数学一样需要其它的Markdown语法支持,请也使用插件. )
你可以用这个 remark-plugins 要通过评论插件的道具 .
npm install remark-gfm
<script setup lang="ts">
import { VueMarkdown } from '@crazydos/vue-markdown'
import remarkGfm from 'remark-gfm'
import { ref } from 'vue'
const markdown = ref(`## Hello World
- [x] Add some task
- [ ] Do some task
`)
</script>
<template>
<!-- simple usage -->
<VueMarkdown :markdown="markdown" :remark-plugins="[remarkGfm]" />
</template>
渲染html
默认, vue-markdown 输出 HTML 作为纯文本.
如果要制作 HTML 标记,需要使用 rehype-raw 插件 .
npm install rehype-raw
<script setup lang="ts">
import { VueMarkdown } from '@crazydos/vue-markdown'
import rehypeRaw from 'rehype-raw'
import { ref } from 'vue'
const markdown = ref(`
<details>
<summary>Details</summary>
Something small enough to escape casual notice.
</details>
`)
</script>
<template>
<VueMarkdown :markdown="markdown" :rehype-plugins="[rehypeRaw]" />
</template>
同步插件
[注] 来自 v2+ 的支持
@crazydos/vue-markdown 支持使用United async插件(例如). @shiki/雷希佩) (中文(简体) ). 当使用同位素插件时,必须使用 <VueMarkdownAsync> 把它包起来 <Suspense> 以正确渲染内容. <VueMarkdownAsync> 共享与 <VueMarkdown>,包括相同的道具和插槽.
<script setup lang="ts">
import rehypeShiki from '@shikijs/rehype'
</script>
<template>
<Suspense>
<VueMarkdownAsync
:markdown="markdown"
:rehype-plugins="[rehypeShiki, { theme: 'github-light' }]"
/>
</Suspense>
</template>
自定义属性
您可以自定义单个 HTML 元素的标记, 例如, 添加默认类或设置类似属性 target, (中文(简体) ), rel, (中文(简体) ), lazyload等 (中文(简体) ). 风俗会传入Vue h 函数,因此其效果与将属性传递给 h请参考 Vue的正式文件 以了解不同数据类型的效应 h 函数.
<script setup lang="ts">
import { type CustomAttrs, VueMarkdown } from '@crazydos/vue-markdown'
import { ref } from 'vue'
const markdown = ref(`
# Hello world
## Hello World 2
[Google](https://www.google.com)
`)
const customAttrs: CustomAttrs = {
// use html tag name as key
h1: { class: ['heading'] },
h2: { class: ['heading'] },
a: { target: '_blank', rel: 'noopener noreferrer' }
}
</script>
<template>
<VueMarkdown :markdown="markdown" :custom-attrs="customAttrs" />
</template>
customAttrs 提供一些高级功能:通过一个功能进行更灵活的配置.
const customAttrs: CustomAttrs = {
h1: { class: ['heading'] },
h2: { class: ['heading'] },
a: (node, combinedAttrs) => {
if (
typeof node.properties.href === 'string'
&& node.properties.href.startsWith('https://www.google.com')
) {
return { target: '_blank', rel: 'noopener noreferrer' }
}
else {
return {}
}
}
}
- 一些标记也有别名,例如:
heading别名可用于h1结束h6标签.
例如,如果我们要配置如下:
const customAttrs: CustomAttrs = {
h1: { class: ['heading'] },
h2: { class: ['heading'] },
}
这相当于:
const customAttrs: CustomAttrs = {
heading: { class: ['heading'] }
}
它也可以接受一个配置功能.
// will set
// class="heading heading-1" for h1
// class="heading heading-2" for h2
// .......
const customAttrs: CustomAttrs = {
heading: (node, combinedAttrs) => {
return { class: ['heading', `heading-${combinedAttrs.level}`] }
}
}
请参看 医生,检查该函数可以接受的参数.
自定义带有范围槽的标签渲染
这个功能比较麻烦 Vue如果 customAttrs 无法满足你的需要, 你可以自定义标签通过 scoped slot。 。 。 .
<VueMarkdown
markdown="## hello world"
>
<template #h2="{ children, ...props }">
<h1 v-bind="props">
<Component :is="children" />
</h1>
</template>
</VueMarkdown>
如果你想在示例中显示"你好世界"的文字,就需要制作 children。您可以得到 children 从插槽道具, 它代表 children 会 议 日 程 和 议 程 h1既然我把它变成一个功能组件 你必须让它使用 <Component>。您还可以制取 children 随所取地.
测距槽收到的参数基本相同. 然而,有些时段可能会得到特殊的参数;例如,在 ul 元素,它可能会收到 depth,在列表中显示巢穴级别,并指定其为哪个级别.
<VueMarkdown
:markdown="`## title
- list 1
- list 2
- list 3
`"
>
<template #ul="{ children, depth, ...props }">
<ul :class="['unordered-list', `list-depth-${depth}`]">
<Component :is="children" />
</ul>
</template>
</VueMarkdown>
此外,同样地,范围槽也提供了与HTML标记别名相同的HTML标记 customAttrs。可以使用化名插入槽中.
<template>
<VueMarkdown
markdown="
# hello world
## hello world
### hello world
#### hello world
##### hello world
###### hello world
"
>
<template
#heading="{
children,
level,
key,
// ...props
}"
>
<MyCustomHeading :key="key" :level="level">
<Component :is="children" />
</MyCustomHeading>
</template>
</VueMarkdown>
</template>
欲了解更多情况,请参考 范围槽
重交问题
我建议在母部分保留状态,然后传给定制部分。 当您的 Markdown 变化时, 特别是在执行编辑器特性时, 元素在树节点的位置会经常改变, 导致内部的组件间歇地重挂, 重新设置状态( 即使增加了密钥) .
使用 <slot> 减值
你可以用这个 <slot> 语法在Markdown中,但需要配置以下内容:
- 设置
rehype-raw插件 - 设定
:sanitize="false"
npm install rehype-raw
在下面的例子中,我们在Markdown中写入Vue-like槽语法,并且可以从母元件中插入这个槽. 同时可以获得槽道具.
目前, 它不支持 Vue 模板语法 v-bind (支持这一点会比较有挑战性).
[尖叫声] 在此之前
v0.2.0请使用<slot name="custom" />指定槽名
<script setup lang="ts">
import { VueMarkdown } from '@crazydos/vue-markdown'
import remarkRaw from 'rehype-raw'
import { ref } from 'vue'
const markdown = ref(`
## Hello Slot
<slot slot-name="custom" msg="Insert from vue component"></slot>
`)
</script>
<template>
<!-- simple usage -->
<VueMarkdown :markdown="markdown" :rehype-plugins="[remarkRaw]" :sanitize="false">
<!-- use 's-' + 'slot-name' -->
<template #s-custom="{ msg }">
<span> {{ msg }} </span>
</template>
</VueMarkdown>
</template>
警卫
为了防御各种攻击(例如XSS),我们使用 rehype-sanitize 内部统一插件。 为了启用,请添加 :sanitize="true"。 。 。 .
参见 rehype-sanitize 用于配置细节的文档.
以下是阻止所有 HTML 标记的渲染,仅显示文本的示例配置 :
<script setup lang="ts">
import { type SanitizeOptions, VueMarkdown } from '@crazydos/vue-markdown'
import { ref } from 'vue'
const sanitizeOption: SanitizeOptions = {
// Please pass the parameters of rehype-sanitize into the sanitizeOptions:
sanitizeOptions: {
tagNames: [],
},
// mergeOptions: Optional. Internally, we use the `deepmerge` package to combine `defaultSchema` and `sanitizeOptions`. You can adjust the merging behavior in `mergeOptions`.
mergeOptions: {
arrayMerge: (target, source) => {
return source
},
},
}
</script>
<template>
<VueMarkdown
:markdown="content"
:custom-attrs="customAttrs"
:remark-plugins="[remarkGfm]"
:rehype-plugins="[rehypeRaw]"
:sanitize-options="sanitizeOption"
sanitize
/>
</template>
文档
<VueMarkdown> 打开 <VueMarkdownAsync> 道具
| Prop | 说明 | 类型 | 默认 | 示例 |
|---|---|---|---|---|
markdown | 下沉内容 | string | '' | |
customAttrs | 您可以为每个元素设置自定义属性, 例如 href, (中文(简体) ), target, (中文(简体) ), rel, (中文(简体) ), lazyload等 (中文(简体) ). 键是 HTML 标签名,值可以是对象,也可以是返回对象的函数. 该值将传递给Vue's h 函数。 您可以参考Vue的官方文档来学习配置 h。 。 。 . | CustomAttrs | {} | { img: { lazyload: true } }{ h1: (node, combinedAttrs) => { return { class: ['title', 'mb-2'] } }} |
remarkPlugins | 标记插件 。 这些插件将在之间使用 remark-parse 财务报告和审定财务报表 remark-rehype。见 https://github.com/remarkjs/remark?tab=readme-ov-file#plugins (中文(简体) ) | PluggableList | [] | |
rehypePlugins | 复韵插件. 这些插件将在之后使用 remark-rehype 不过在 rehype-sanitize。见 https://github.com/remarkjs/remark-rehype?tab=readme-ov-file#相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相關相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相 | PluggableList | [] | |
sanitize | 是否对 HTML 内容进行消毒 。 (使用时 rehype-sanitize) (中文(简体) ). 如果您想要渲染, 您需要禁用此选项 <slot> 在减值内容. | boolean | false | |
sanitizeOptions | 备选方案 rehype-sanitize。参见: https://github.com/syntax-tree/hast-util-sanitize#schema (英语) | SanitizeOptions | { allowDangerousHtml: true } | |
rehypeOptions | 备选方案 rehype-parse。参见: https://github.com/remarkjs/remark-rehype?tab=readme-ov-file#可选办法 互联网档案馆的存檔,存档日期2014-12-02 | Omit<TRehypeOptions, 'file'> | {} |
scoped slot 财务报告和审定财务报表 custom attrs
在范围档和 customAttrs,可以接收额外的参数。 除了可以在Markdown中设置的HTML属性外, vue-markdown 还提供了其他参数.
| 标记 | 参数 | 类型 | 说明 |
|---|---|---|---|
| 所有元素 | 元素上的任何 HTML 属性 | 字符串 | alt, (中文(简体) ), title等,还有... |
h1 ~ (法语) h6, (中文(简体) ), heading | level | number | 系标题 |
h1 ~ (法语) h6, (中文(简体) ), heading | level | number | 系标题 |
code, (中文(简体) ), inline-code, (中文(简体) ), block-code | language | string | 代表语言。 例如: js, (中文(简体) ), sh, (中文(简体) ), md . |
languageOriginal | string | 典型的形式是: language- 之后是语言,例如, language-js, (中文(简体) ), language-sh. 与语言参数相类似,但语言提供了更简单的表示. | |
inline | boolean | 内置代码或块代码 | |
content | string | 代码的文本内容字符串 。 ()v0.3.0+ (韩语)) (中文(简体) ). 参见代码示例 | |
th, (中文(简体) ), td, (中文(简体) ), tr | isHead | boolean | 说明是否在 thead。 。 。 . |
list, (中文(简体) ), ol, (中文(简体) ), ul | ordered | boolean | 说明它是 ordered-list 或无. |
depth | number | 在嵌入式列表中,它表示列表位置的级别. 第一个关卡是0. | |
list-item, (中文(简体) ), li | ordered | boolean | 说明是否在 ordered-list 或无. |
depth | number | 在嵌入式列表中,它表示列表位置的级别. 第一个关卡是0. | |
index | number | 代表清单项目在其现有水平内的立场。 任何级别的第一个项目都被视为0. |
属性别名
属性别名可用于两者的配置 scoped slot 财务报告和审定财务报表 customAttrs。一般情况下,如果使用别名进行配置或插入插槽,则别名配置将优先于其相应的HTML标记.
| 别名 | HTML 标记 |
|---|---|
heading | h1, (中文(简体) ), h2, (中文(简体) ), h3, (中文(简体) ), h4, (中文(简体) ), h5, (中文(简体) ), h6 |
list | ol, (中文(简体) ), ul |
list-item | li |
inline-code | code (内行) |
block-code | code (块入 pre 标签) |
代码内容示例
<!-- For example -->
<template>
<VueMarkdown :markdown="markdown">
<template #code="{ children, ...props }">
<MyCustomCodeBlock :code="props.content" :lang="props.language" />
<!-- Or -->
<code>
<component :is="children" />
</code>
</template>
</VueMarkdown>
</template>
参考文献
反应- 标记。 。 。 .
许可证
麻省理工学院