Katex

相关内容

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

Vue - TypeError: Cannot read properties of null (reading 'insertBefore')

In Vue 3/Nuxt 3, one may occur the error TypeError: Cannot read properties of null (reading 'insertBefore') which has little information and is hard to solve. In the following, we summerize some tips that help you solve this error :1. Change v-if to v-show , or change all v-if , v-else to v-show. Sometimes, the error appears because there are v-if or v-if, v-else pairs.2. Change katex auto-render. The error may appear because you use katex auto-render. To solve this, you could either change katex to mathjax, or change document.body in the auto-render function to a specific area document.getElementById(Id) as follows :<script> 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>If katex render all corresponding symbols in document.body, it may also influence some normal part. So you need to restrict it to a specific area.3. Change your dialog component. If you are using SSR, like Nuxt.js, the error may occur due to your dialog component in the UI library. You could either try to wrap the dialog with ClientOnly <ClientOnly> <Dialog> </Dialog> </ClientOnly>or try to use another UI library.
2024-05-05 12:19:38