vue---实现流式打印文字和Katex渲染公式

由于没使用sse,后端把数据一下返回过来了,只能前端做假的流式了,我用的是vue3,参考一下吧

首先介绍一下公式渲染

Katex插件渲染的公式,具体怎么配置,去官网看看吧,我这直接使用,

之前用的这个插件mathjax,这个是不需要打印的时候。只要检测到页面有公式,就会渲染,但是这种一个一个的打印出来的,识别不到,而且会造成页面很卡,加载也慢,不推荐。

安装插件,我这里没有全局引入,直接安装就行了,目前没碰到版本问题。

perl 复制代码
"markdown-it": "^13.0.2",
"markdown-it-katex": "^2.0.3",
"@iktakahiro/markdown-it-katex": "^4.0.1",

dom结构

ini 复制代码
<div class="chat-box" id="chat-box" @wheel="wheelChange">
    <div ref="chatReplyRef" v-html="outputText"></div>
</div>
//方法就是监听一下,数据是否存在
const whellStatus = ref(false);
const wheelChange = () => {
 if (chatData.value.length) {
   whellStatus.value = true;
 }
};

打印的方法

公式格式,我这边的是

bash 复制代码
$S_x=\\dfrac {BH^2}{8}=\\dfrac {1×10^2}{8}=1.25\\times 10^{1}mm^3\\\\$

里面的数学公式要用\\两个斜杠,\\\\四个斜杠代表换行,尽量避免 <math xmlns="http://www.w3.org/1998/Math/MathML"> 里面有中文 里面有中文 </math>里面有中文,会报警告,会卡顿,控制台一直打印,所以我这边用了 strict: "ignore" 设置为忽略非法警告。。

在这个插件中,我控制的这个div中,插件不会自动换行,,,

解决办法是,,给插件设置,我在html里面设置的,当然,也要给div设置换行的css,这就可以正常显示了

word-wrap: break-word; 换行css

xml 复制代码
  <style>
    .katex .base {
    display: contents !important;
    }
  </style>
ini 复制代码
const currentIndex = ref(0); //索引
const outputText = ref(""); //回答问题
let md = require("markdown-it")();
let mk = require("@iktakahiro/markdown-it-katex");
md.use(mk, {
  strict: "ignore", // 设置为忽略非法警告
});
const typeOut = function () {
  const textToShow = props.content;
  if (currentIndex.value < textToShow.length) {
    if (textToShow[currentIndex.value] === "<") {
      currentIndex.value = currentIndex.value + 4;
    }
      //优化滚动
    const chatBox = document.getElementById("chat-box");
    chatBox.scrollTo(0, document.getElementById("chat-box").scrollHeight);
    const newText = textToShow.slice(0, currentIndex.value + 1);
    currentIndex.value = currentIndex.value + 1;    
    
    
    //给要显示的的赋值
    outputText.value = md.render(newText);
    setTimeout(typeOut, 0); //每隔50毫秒显示下一个字
  } else {
    setTimeout(() => {
      const chatBox = document.getElementById("chat-box");
      chatBox.scrollTo(0, document.getElementById("chat-box").scrollHeight);
    });
  }
};

mathjax渲染公式(不推荐)

首先就是安装,自己去安装吧

创建一个mathjax.js,公式检测到 <math xmlns="http://www.w3.org/1998/Math/MathML"> 公式 公式 </math>公式,反正就这几个包裹住的,就可以渲染了

swift 复制代码
window.MathJax = {
  tex: {
    inlineMath: [
      ["$", "$"],
      ["\\(", "\\)"],
      ["\\", "\\"],
    ], // 行内公式选择符
    displayMath: [
      ["&", "&"],
      ["$", "$"],
      ["$$", "$$"],
      ["\\[", "\\]"],
    ], // 段内公式选择符
  },
  startup: {
    ready() {
      let styles = MathJax._.output.svg.Wrappers.math.SVGmath.styles;
      // console.log(MathJax._.output.svg.Wrappers.math.SVGmath.styles);
      styles['mjx-container[jax="SVG"][display="true"]'].margin = "0.2em 0";
      styles['mjx-container[jax="SVG"][display="true"]']["text-align"] = "left";
      styles['mjx-container[jax="SVG"][display="true"]']["font-size"] = "12px";
      MathJax.startup.defaultReady();
    },
    promise: Promise,
  },
};

在main.js中最前面引入

import "@/utils/mathjax"; // 必须在引入mathjax前引入mathjax的配置文件

使用的话,在需要的页面中

scss 复制代码
onMounted(() => {
  setTimeout(() => {
     window.MathJax.typesetPromise();
  });
});
相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试