一、初始问题
-
使用
vue3-markdown-it
组件时出现错误Module not found: Error: Can't resolve 'babel-runtime/core-js/get-iterator'
-
原因:
vue3-markdown-it
是为 Vue 2 设计的,依赖了旧版babel-runtime
和core-js
-
-
安装
vue3-markdown-it
后仍报错Module not found: Error: Can't resolve 'vue-vue3-markdown-it'
-
原因:
vue3-markdown-it
的导入名称与实际不符
-
二、解决方案对比
方案 | 优点 | 缺点 |
---|---|---|
1. 改用 vue3-markdown-it | 直接支持 Vue 3,功能较完整 | 需处理旧版依赖问题 |
2. 使用 markdown-it + v-html | 纯 JavaScript 实现,无额外依赖 | 需手动处理 HTML 转义 |
3. 使用其他 Markdown 组件 | 可能有更丰富的功能 | 需重新学习新组件 API |
三、最终推荐方案:markdown-it
+ v-html
1. 安装依赖
npm install markdown-it dompurify --save
2. 组件实现示例
模板部分
html
<template>
<div class="markdown-content" v-html="parsedMarkdown"></div>
</template>
脚本部分
javascript
<script>
import { marked } from 'marked';
import DOMPurify from 'dompurify';
export default {
props: {
content: {
type: String,
default: ''
},
options: {
type: Object,
default: () => ({
breaks: true,
linkify: true,
typographer: true
})
}
},
computed: {
parsedMarkdown() {
// 使用 marked 解析 Markdown
const html = marked(this.content, this.options);
// 使用 DOMPurify 净化 HTML
return DOMPurify.sanitize(html);
}
}
}
</script>
样式部分
css
<style scoped>
.markdown-content {
line-height: 1.6;
}
.markdown-content img {
max-width: 100%;
}
.markdown-content pre {
background: #f5f5f5;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
.markdown-content code {
background: #f0f0f0;
padding: 2px 4px;
border-radius: 2px;
}
.markdown-content blockquote {
border-left: 4px solid #ddd;
padding-left: 10px;
color: #666;
}
</style>
3. 高级功能扩展
添加 Markdown 解析器配置
javascript
import { marked } from 'marked';
import { highlight } from 'highlight.js';
import 'highlight.js/styles/github.css';
// 配置 marked
const md = new marked.Marked({
highlight: function(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return highlight(code, { language }).value;
},
breaks: true,
smartLists: true,
smartypants: true
});
// 在组件中使用
computed: {
parsedMarkdown() {
return DOMPurify.sanitize(md.parse(this.content));
}
}
定义渲染器
const renderer = new marked.Renderer();
// 自定义链接渲染
renderer.link = function(href, title, text) {
return `<a href="${href}" target="_blank" rel="noopener noreferrer"${title ? ` title="${title}"` : ''}>${text}</a>`;
};
const md = new marked.Marked({ renderer });
四、常见问题及解决
1. 表格不显示
| 表头1 | 表头2 | |-------|-------| | 内容1 | 内容2 |
解决:确保表格格式正确,列数一致
2. 图片不显示

解决:检查图片路径是否正确,或使用绝对路径
3. 代码高亮无效
1. 安装 highlight.js 2. 配置 marked 使用 highlight.js 3. 添加样式
五、最佳实践建议
-
始终使用 DOMPurify 净化 HTML,特别是当内容来源不可信时
-
配置合理的 XSS 防护:
const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['h1', 'h2', 'p', 'a', 'img', 'code', 'pre', 'em', 'strong'], ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'target'] });
-
处理大段 Markdown 内容:
-
使用虚拟滚动
-
分块渲染
-
延迟加载图片
-
-
自定义样式:
/* 覆盖默认样式 */ .markdown-content h1 { color: #333; border-bottom: 1px solid #eee; padding-bottom: 0.5em; }
六、性能优化
-
使用 Web Worker 解析:
// main.js const worker = new Worker('markdown-worker.js'); worker.postMessage({ content: markdownText }); worker.onmessage = (e) => { this.parsedMarkdown = e.data.html; };
-
缓存解析结果:
const cache = new Map(); function getMarkdownHtml(markdown) { if (cache.has(markdown)) { return cache.get(markdown); } const html = md.parse(markdown); cache.set(markdown, html); return html; }
-
懒加载高亮库:
// 按需加载 highlight.js import('highlight.js').then(hljs => { // 使用 hljs });
七、总结
需求 | 解决方案 |
---|---|
基础 Markdown 渲染 | 使用 marked + v-html |
安全防护 | 使用 DOMPurify 净化 HTML |
代码高亮 | 集成 highlight.js |
表格支持 | 确保 Markdown 表格格式正确 |
图片显示 | 检查路径或使用绝对路径 |
大段内容优化 | 虚拟滚动/分块渲染 |
自定义样式 | 覆盖默认样式类 |
通过以上方案,可以解决 Vue3 前端中 Markdown 渲染的各种常见问题,并提供良好的用户体验和安全性。