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