·

Vue或Nuxt中如何渲染数学公式?

发布时间:2024-06-06 16:13:27阅读量:1126
转载请注明来源

在网页上,有很多种方法可以渲染漂亮的数学公式。但是这些方法基本上不能直接应用于Vue.js或者Nuxt.js。在本文中,我们将分别说明如何在Vue.js或者Nuxt.js中使用katexmathjax渲染数学公式。

Katex

想要自动渲染所有页面上的数学公式,你需要使用CDN来加载katex

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/poem-studio-favicon-black.svg">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css" integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" crossorigin="anonymous">
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js" integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" crossorigin="anonymous"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous"
    onload="renderMathInElement(document.body);"></script>
    <title>Manitori</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

如果你使用的是Nuxt.js,那么你需要修改你的nuxt.config.ts

//nuxt.config.ts

export default defineNuxtConfig({
  app: {
    head: {
      link: [
        {rel:'stylesheet', href:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css", integrity:"sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww", crossorigin:"anonymous"}
      ],
      script: [
        {
          defer:true,
          src:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js", 
          integrity:"sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd", 
          crossorigin:"anonymous"
        },
        {
          defer:true, 
          src:"https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js", 
          integrity:"sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk", 
          crossorigin:"anonymous",
          onload:"renderMathInElement(document.body);"
        },
       ]
    }
  }

})

如果你需要更改renderMathInElement函数的选项,你可以在另一个<script>标签中调用renderMathInElement

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/poem-studio-favicon-black.svg">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css" integrity="sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" crossorigin="anonymous">
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js" integrity="sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" crossorigin="anonymous"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous"></script>
    <script>
    document.addEventListener("DOMContentLoaded", function() {
      renderMathInElement(document.body, {
          // customised options
          // • auto-render specific keys, e.g.:
          delimiters: [
              {left: '$$', right: '$$', display: true},
              {left: '$', right: '$', display: false},
              {left: '\\(', right: '\\)', display: false},
              {left: '\\[', right: '\\]', display: true}
          ],
          // • rendering keys, e.g.:
          throwOnError : false
        });
    });
    </script>
    <title>Manitori</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

需要注意的是,直接使用document.body可能会导致一些关键性错误,见Vue - TypeError: Cannot read properties of null (reading 'insertBefore')。因此,建议将document.body 改为一个特定的渲染区域document.getElementById(Id) ,不过这样的话,你需要每一页都分别调用一次renderMathInElement

<script lang="ts" setup>
onMounted(()=>{
  nextTick(()=>{
    var node = document.getElementById(Id)
    document.addEventListener("DOMContentLoaded", function() {
      renderMathInElement(node, {
        // customised options
        // • auto-render specific keys, e.g.:
        delimiters: [
          {left: '$$', right: '$$', display: true},
          {left: '$', right: '$', display: false},
          {left: '\\(', right: '\\)', display: false},
          {left: '\\[', right: '\\]', display: true}
        ],
        // • rendering keys, e.g.:
        throwOnError : false
      });
    });
  })
})
</script>

在Vue.js中,你估计需要异步渲染数学公式,因此可以根据以下示例写:

<script lang="ts" setup>
var node = document.getElementById(Id)

Promise.resolve()
.then(()=>{
  nextTick(()=>{
    document.addEventListener("DOMContentLoaded", function() {
      renderMathInElement(node, {
        // customised options
        // • auto-render specific keys, e.g.:
        delimiters: [
          {left: '$$', right: '$$', display: true},
          {left: '$', right: '$', display: false},
          {left: '\\(', right: '\\)', display: false},
          {left: '\\[', right: '\\]', display: true}
        ],
        // • rendering keys, e.g.:
        throwOnError : false
      });
    });
  })
})
</script>

Mathjax

mathjax来自动渲染数学公式,比katex要简单得多。跟katex一样,你最好使用CDN来加载mathjax

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/poem-studio-favicon-black.svg">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" id="MathJax-script" async
    src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-chtml.js">
  </script>
  <script>
    MathJax = {
      tex: {
        inlineMath: [['$', '$'], ['\\(', '\\)']]
      }
    };
    </script>
    <title>Manitori</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

如果你使用的是Nuxt.js,那么在你的nuxt.config.ts 中添加如下代码:

//nuxt.config.ts

export default defineNuxtConfig({
  app: {
    head: {

      script: [
        {
          type: "text/javascript",
          id: "MathJax-script",
          async: true,
          src: "https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.6/tex-chtml.js",
        },
        {
          innerHTML:
            "MathJax = {tex: {inlineMath: [['$', '$'],['$$', '$$']]}};",
        },
      ]
})

然而在Vue.js中,使用mathjax,你也需要异步渲染数学公式。不然,所有渲染的数学公式都会重新变回原样。为此,你需要使用MathJax.typesetPromise()

<script lang="ts" setup>
Promise.resolve()
.then(()=>{
  nextTick(() => {
    MathJax.typesetPromise();
  });
})
</script>

或者你可以使用setTimeout来替代nextTick:

setTimeout(() => {
  MathJax.typesetPromise();
}, 3000);

根据上面的做法,你就可以轻松在Vue.js或Nuxt.js中整合katex和mathjax啦😄!

0 人喜欢

评论区

暂无评论,来发布第一条评论吧!

弦圈热门内容

数说心语 | 一直在出发

数说心语#一直在出发#亲爱的同学们你是否因为昨日事务的束缚明天前途的焦虑而停下了当下探索的脚步在此数院团学君为同学们推荐汪国真先生的《我喜欢出发》愿大家不要失去随时出发的勇气《我喜欢出发》汪国真我喜欢出发。凡是到达了的地方,都属于昨天。哪怕那山再青,那水再秀,那风再温柔。太深的流连便成了一种羁绊,绊住的不仅有双脚,还有未来。怎么能不喜欢出发呢?没见过大山的巍峨,真是遗憾;见了大山的巍峨,没见过大海的浩瀚,仍然遗憾;见了大海的浩瀚,没见过大漠的广袤,依旧遗憾;见了大漠的广袤,没见过森林的神秘,还是遗憾。世界上有不绝的风景,我有不老的心情。我自然知道,大山有坎坷,大海有浪涛,大漠有风沙,森林有猛兽。即便这样,我依然喜欢。打破生活的平静便是另一番景致,一种属于年轻的景致。真庆幸,我还没有老。即便真老了又怎么样,不是有句话叫老当益壮吗?于是,我还想从大山那里学习深刻,我还想从大海那里学习勇敢,我还想从大漠那里学习沉着,我还想从森林那里学习机敏。我想学着品味一种缤纷的人生。人能走多远?这话不是要问两脚而是要问志向;人能攀多高?这事不是要问双手而是要问意志。于是,我想用青春的热血给自己树起一个高远 ...

你对自己的哪本数学启蒙书印象最深刻?

相信每一个喜欢数学的人,都曾被某几本书中描述的数学内容所深深震撼,从而一发不可收拾的踏上数学这条“不归路”😂。 我至今还记得初三高一的时候,自己第一次看代数几何的那种震撼(GTM52),当时的我涉猎过泛函分析、范畴论、微分几何等数学分支,但唯有代数几何给予我心灵上最大的震撼。 我为代数几何这个艰深、深奥、广阔、神秘的领域所深深吸引,加上当时知道了Grothendieck的事迹,让我下定决心攻克代数几何的重重难关,只为更接近心中的“神”😂。 不知道你的数学启蒙书是哪几本呢?其中哪本书你印象最深刻呢?