Mathjax

相关内容

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

在网页上,有很多种方法可以渲染漂亮的数学公式。但是这些方法基本上不能直接应用于Vue.js或者Nuxt.js。在本文中,我们将分别说明如何在Vue.js或者Nuxt.js中使用katex和mathjax渲染数学公式。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啦😄!
2024-06-06 16:13:27