mathpix-markdown-it 在VUE项目中流式数据的使用

2,268 阅读2分钟

mathpix-markdown-it 介绍

mathpix-markdown-it 是一个开源项目,旨在为科学社区提供一个增强版的 Markdown 渲染工具。它支持 LaTeX 语法,特别适用于需要处理复杂数学公式、表格和化学公式的场景。Mathpix Markdown-it 通过 MathJax 渲染数学公式,并依赖 markdown-it 进行标准 Markdown 解析。

项目背景

通过调用openai接口,实时返回数据,并把数据正常渲染到页面中,如果含有代码的话,高亮显示,含有相关公式的话,正常显示。

npm地址:www.npmjs.com/package/mat…

安装

你可以通过 npm 或 yarn 安装 Mathpix Markdown-it:

# 使用 npm 安装
npm install mathpix-markdown-it

mathpix-markdown-it例子地址:github.com/Mathpix/mat…

VUE项目中使用

# 相关页面引入
import {MathpixMarkdownModel as MM} from "mathpix-markdown-it";
import 'highlight.js/styles/a11y-dark.css';
 methods: { 
    compiledMarkdown(val) {
      const isLoad = MM.loadMathJax();
      if(isLoad){
        return MM.markdownToHTML(val,{
          htmlTags: true,
          codeHighlight: {
            auto: true,
            code: true
          }
        })
      }
    },
  }

# 模板中使用
<div v-html="compiledMarkdown(streamingText)" class="markdown-define"></div>
题外话:如果需要对页面中的代码单独设置[复制按钮]的话,可以设置,即:把
  htmlTags: true,
  codeHighlight: {
    auto: true,
    code: true
  },
  copyToClipboard: true
 }

但是设置的话,会对实时输出的数据有个显示问题,那就是在代码输出过程中,复制按钮就已经显示,但是复制不到文案,是因为addListenerCopyToClipdoardEvents()这个函数还没有调用,它是需要代码手动触发调用的。所以当流式数据传输中,无法复制,但是又显示了按钮,对用户不太友好,看“文言一心”中,是在渲染后才出现复制代码功能,所以针对这个功能,需要自己实现。

# 不是流式处理的代码:
addCopyButtons() {
  const btns = this.$el.querySelectorAll('clipboard-copy');
  btns.forEach((btn) => {
    btn.addEventListener('click', function(event) {
      addListenerCopyToClipdoardEvents();
    });
  });
},
# 使用
watch: {
    streamingText(val){
      if(val){
      }else{
        this.$nextTick(() => {
          this.addCopyButtons()
        })
      }
    },
  },
  
# 流式代码:
addCopyButtons() {
  const codes = this.$el.querySelectorAll('pre code');
    codes.forEach((code) => {
    const existingButton = code.parentElement.querySelector('.copy-btn');
    if (!existingButton) {
      const button = document.createElement('p');
      button.innerText = '复制代码';
      button.className = 'copy-btn';

      button.addEventListener('click', function(event) {
        Vue.nextTick(() => {
          handleClipboard(code.innerText, event);
        });
      });
      code.parentElement.prepend(button);
    }
  });
},
    
    # 使用方法同上
好的,以上就是在项目中的使用,看效果吧

代码: image.png 公式: image.png