在 Vue 项目中使用 MarkdownIt 及插件(Mermaid、Katex等)实现问答内容动态渲染

前言

Markdown 是一种广受欢迎的轻量级标记语言,便于书写和格式化内容。在实际开发中,我们常常需要在项目中动态渲染 Markdown 内容,同时满足高亮代码块、支持公式渲染或流程图绘制等扩展需求。本文将通过一个 Vue 示例,讲解如何结合 MarkdownIt 和相关插件实现 Markdown 内容的动态展示。

效果预览

我们将实现一个问答界面:

  • 用户的提问和回答会动态渲染。
  • Markdown 支持多种格式扩展,如任务列表、公式(KaTeX)、流程图(Mermaid)等。

技术实现

1. 项目依赖安装

我们需要安装以下依赖(根据自己的需求去安装插件):

npm install markdown-it highlight.js katex mermaid markdown-it-sub markdown-it-sup markdown-it-emoji markdown-it-task-lists markdown-it-footnote markdown-it-deflist markdown-it-abbr markdown-it-ins markdown-it-mark

2. MarkdownIt 配置

在 Vue 组件中,首先初始化 MarkdownIt 实例,并加载所需插件:

import MarkdownIt from 'markdown-it';
import hljs from 'highlight.js';
import mermaid from 'mermaid';
const katex = require('katex');
import MarkdownItMermaid from '@/utils/markdown-it-plugin-mermaid';
import 'katex/dist/katex.min.css';
import 'highlight.js/styles/default.css';


mermaid.initialize({ startOnLoad: true });

const mdi = new MarkdownIt({
  html: true,
  xhtmlOut: true,
  breaks: true,
  langPrefix: 'language-',
  linkify: true,
  typographer: true,
  quotes: '“”‘’',
  highlight: (str, lang) => {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<pre class="hljs"><code>${hljs.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre>`;
      } catch (__) {}
    }
    return `<pre class="hljs"><code>${mdi.utils.escapeHtml(str)}</code></pre>`;
  },
})
  .use(require('markdown-it-sub'))
  .use(require('markdown-it-sup'))
  .use(require('markdown-it-emoji'))
  .use(require('markdown-it-task-lists'))
  .use(require('markdown-it-footnote'))
  .use(require('markdown-it-deflist'))
  .use(require('markdown-it-abbr'))
  .use(require('markdown-it-ins'))
  .use(require('markdown-it-mark'))
  .use(MarkdownItMermaid);

3.渲染html

...
<div v-html="initPage(item[0])"></div>
...

initPage(item){
      return mdi.render(this.preprocessMarkdown(item));// 将文章内容片段组合并渲染
    },
preprocessMarkdown(markdownText) {
      const inlineMathRegex = /\$([^\$]+?)\$/g;
      markdownText = markdownText.replace(inlineMathRegex, (match, tex) => {
        try {
          return katex.renderToString(tex, {
            throwOnError: true,
            displayMode: false,
            globalGroup: true,  // or use \global\let
            macros:{
              "\\RR": "\\mathbb{R}",
            },
            output:'html',
          });
        } catch (e) {
          return `<span class="error">Error rendering math: ${e.message}</span>`;
        }
      });
      // 使用正则表达式匹配块级LaTeX数学公式
      const blockMathRegex = /\$\$([\s\S]*?)\$\$/g;
      markdownText = markdownText.replace(blockMathRegex, (match, tex) => {
        try {
          return '<div class="math-block">' + katex.renderToString(tex, {
            throwOnError: true,
            displayMode: false,
          }) + '</div>';
        } catch (e) {
          return `<div class="math-block error">Error rendering math: ${e.message}</div>`;
        }
      });

      return markdownText;
    },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值