·

How to render math in Vue or Nuxt?

Published at 2024-06-06 16:13:27Viewed 736 times
Professional article
Please reprint with source link

There are several ways to write and render beautiful math on web. However, some methods can't be directly applied to Vue.js/Nuxt.js. In this article, we will explain how to use katex and mathjax to render math in Vue.js/Nuxt.js.

Katex

To automatically render all math in all the pages, you need to use CDN to load 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>

If you are using Nuxt.js, then you need to change your 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);"
        },
       ]
    }
  }

})

If you want to specify the options of the renderMathInElement function, you could call renderMathInElement in another <script> :

<!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>

Note that you'd better change document.body to a specific area document.getElementById(Id), otherwise, it may cause some fatal error, see Vue - TypeError: Cannot read properties of null (reading 'insertBefore').

To render math in a specific area, you need to call renderMathInElement separately in each page. For example:

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

In Vue.js, you may need to asynchronously render math, so you can follow this example:

<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

It is easy to automatically render all math using mathjax. Like katex, you'd better use CDN to load 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>

If you are using Nuxt.js, then change your nuxt.config.ts like this:

//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: [['$', '$'],['$$', '$$']]}};",
        },
      ]
})

However, in Vue.js you also need to asynchronously render math using mathjax, otherwise, The rendered math formula will revert back to original text. You can call MathJax.typesetPromise() to achieve this. For example:

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

Or you could use setTimeout instead of nextTick:

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

Following our methods, you can easily integrate Vue.js/Nuxt.js with katex and mathjax😄!

0 人喜欢

Comments

There is no comment, let's add the first one.

弦圈热门内容

Django change an existing field to foreign key

I have a Django model that used to look like this:class Car(models.Model): manufacturer_id = models.IntegerField()There is another model called Manufacturer that the id field refers to. However, I realized that it would be useful to use Django's built-in foreign key functionality, so I changed the model to this:class Car(models.Model): manufacturer = models.ForeignKey(Manufacturer)This change appears to work fine immediately, queries work without errors, but when I try to run migrations, Django outputs the following:- Remove field manufacturer_id from car - Add field manufacturer to carDoing this migration would clear all the existing relationships in the database, so I don't want to do that. I don't really want any migrations at all, since queries like Car.objects.get(manufacturer__name="Toyota") work fine. I would like a proper database foreign key constraint, but it's not a high priority.So my question is this: Is there a way to make a migration or something else that allows me to convert an existing field to a foreign key? I cannot use --fake since I need to reliably work across dev, prod, and my coworkers' computers.内容来源于 Stack Overflow, 遵循 CCBY-SA 4.0 许可协议进行翻译与使用。原文链接:Django change an existing field to foreign key

Get connected with us on social networks! Twitter

©2024 Guangzhou Sinephony Technology Co., Ltd All Rights Reserved