Vue3 前端适配 Markdown 格式问题及解决方案

一、初始问题

  1. 使用 vue3-markdown-it 组件时出现错误

    Module not found: Error: Can't resolve 'babel-runtime/core-js/get-iterator'
    • 原因:vue3-markdown-it 是为 Vue 2 设计的,依赖了旧版 babel-runtimecore-js

  2. 安装 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. 图片不显示

![alt text](image.jpg)

解决:检查图片路径是否正确,或使用绝对路径

3. 代码高亮无效

1. 安装 highlight.js
2. 配置 marked 使用 highlight.js
3. 添加样式

五、最佳实践建议

  1. 始终使用 DOMPurify 净化 HTML,特别是当内容来源不可信时

  2. 配置合理的 XSS 防护

    const clean = DOMPurify.sanitize(dirty, {
      ALLOWED_TAGS: ['h1', 'h2', 'p', 'a', 'img', 'code', 'pre', 'em', 'strong'],
      ALLOWED_ATTR: ['href', 'src', 'alt', 'title', 'target']
    });

  3. 处理大段 Markdown 内容

    • 使用虚拟滚动

    • 分块渲染

    • 延迟加载图片

  4. 自定义样式

    /* 覆盖默认样式 */
    .markdown-content h1 {
      color: #333;
      border-bottom: 1px solid #eee;
      padding-bottom: 0.5em;
    }

六、性能优化

  1. 使用 Web Worker 解析

    // main.js
    const worker = new Worker('markdown-worker.js');
    worker.postMessage({ content: markdownText });
    worker.onmessage = (e) => {
      this.parsedMarkdown = e.data.html;
    };

  2. 缓存解析结果

    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;
    }

  3. 懒加载高亮库

    // 按需加载 highlight.js
    import('highlight.js').then(hljs => {
      // 使用 hljs
    });
    
    

七、总结

需求解决方案
基础 Markdown 渲染使用 marked + v-html
安全防护使用 DOMPurify 净化 HTML
代码高亮集成 highlight.js
表格支持确保 Markdown 表格格式正确
图片显示检查路径或使用绝对路径
大段内容优化虚拟滚动/分块渲染
自定义样式覆盖默认样式类

通过以上方案,可以解决 Vue3 前端中 Markdown 渲染的各种常见问题,并提供良好的用户体验和安全性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值