前端直接渲染Markdown,主要技术方案:
1. 使用JavaScript库(最常用)
marked
javascript
// 安装:npm install marked
import { marked } from 'marked';
document.getElementById('content').innerHTML = marked.parse(markdownText);
showdown
javascript
// 安装:npm install showdown
const converter = new showdown.Converter();
document.getElementById('content').innerHTML = converter.makeHtml(markdownText);
remark + rehype
javascript
// 更现代的方案
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const html = await unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeStringify)
.process(markdownText);
2. 浏览器原生方案
使用textarea + 解析
html
<textarea id="markdown-source" style="display:none">
# 标题
这是**粗体**文本
</textarea>
<div id="rendered-content"></div>
<script>
// 需要配合marked或其他库使用
</script>
3. 框架集成方案
React + react-markdown
jsx
import ReactMarkdown from 'react-markdown';
function MarkdownRenderer({ content }) {
return <ReactMarkdown>{content}</ReactMarkdown>;
}
Vue + markdown-it
vue
<template>
<div v-html="compiledMarkdown"></div>
</template>
<script>
import markdownIt from 'markdown-it';
export default {
data() {
return {
markdown: '# Hello World'
};
},
computed: {
compiledMarkdown() {
return markdownIt().render(this.markdown);
}
}
};
</script>
4. 完整示例
html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
<textarea id="input" rows="10" cols="50">
# 标题
## 子标题
- 列表项1
- 列表项2
**粗体** *斜体*
</textarea>
<div id="output"></div>
<script>
const input = document.getElementById('input');
const output = document.getElementById('output');
function updateOutput() {
output.innerHTML = marked.parse(input.value);
}
input.addEventListener('input', updateOutput);
updateOutput(); // 初始渲染
</script>
</body>
</html>
5. 安全考虑
使用DOMPurify防止XSS攻击:
javascript
import DOMPurify from 'dompurify';
import { marked } from 'marked';
const cleanHtml = DOMPurify.sanitize(marked.parse(markdownText));
document.getElementById('content').innerHTML = cleanHtml;
推荐使用marked 或remark,它们性能好、功能完整,且有良好的社区支持。