功能目的
当开发一个小学数学教育辅助平台时,一个关键的功能是能够渲染数学题目和数学公式,使其在用户界面中清晰可见和易于理解。一个功能强大的平台需要能够展示各种数学问题和公式,同时保持用户界面的友好和直观。
技术选择
我先后实验了多个用于渲染markdown或latex的库,包括vue-markdown,marked,以及MathJax等。因为MathJax的bug最少(其他库在渲染公式的时候都会把公式渲染两遍),效果最好
代码实现
1.mathjax.js
let isMathjaxConfig = false// 用于标识是否配置
const initMathjaxConfig = () => {
if (!window.MathJax) {
return
}
window.MathJax.Hub.Config({
// styles:{
// ".MJXc-display":{
// "text-align":"left"
// }
// },
// displayAlign:"left",
showProcessingMessages: false, // 关闭js加载过程信息
messageStyle: 'none', // 不显示信息
jax: ['input/TeX', 'output/HTML-CSS'],
tex2jax: {
inlineMath: [['$', '$'], ['\\(', '\\)']], // 行内公式选择符
displayMath: [['$$', '$$'], ['\\[', '\\]']], // 段内公式选择符
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'a'] // 避开某些标签
},
'HTML-CSS': {
availableFonts: ['STIX', 'TeX'], // 可选字体
showMathMenu: false, // 关闭右击菜单显示
},
})
isMathjaxConfig = true // 配置完成,改为true
}
const MathQueue = function (elementId) {
if (!window.MathJax) {
return
}
window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, document.getElementsByClassName(elementId)]) // 根据class
window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, document.getElementById(elementId)]) // 根据id
}
export default {
isMathjaxConfig,
initMathjaxConfig,
MathQueue
}
这段代码是用于配置和管理 MathJax 在网页中渲染数学公式的功能。
1.isMathjaxConfig 变量
let isMathjaxConfig = false; // 用于标识是否配置完成
2.initMathjaxConfig 函数
const initMathjaxConfig = () => {
if (!window.MathJax) {
return; // 如果 MathJax 未加载,则直接返回
}
window.MathJax.Hub.Config({
showProcessingMessages: false, // 关闭js加载过程信息
messageStyle: 'none', // 不显示信息
jax: ['input/TeX', 'output/HTML-CSS'], // 使用TeX输入和HTML-CSS输出
tex2jax: {
inlineMath: [['$', '$'], ['\\(', '\\)']], // 行内公式选择符
displayMath: [['$$', '$$'], ['\\[', '\\]']], // 段内公式选择符
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code', 'a'] // 避开某些标签
},
'HTML-CSS': {
availableFonts: ['STIX', 'TeX'], // 可选字体
showMathMenu: false, // 关闭右击菜单显示
},
});
isMathjaxConfig = true; // 配置完成,改为true
};
用于初始化 MathJax 的配置。它首先检查 window.MathJax 是否存在,如果不存在则直接返回,不进行配置。
使用 window.MathJax.Hub.Config() 方法来配置 MathJax 的各种选项。
最后,将 isMathjaxConfig 设置为 true,表示 MathJax 已经成功配置。
3.MathQueue 函数
MathQueue 函数用于将待渲染数学公式添加到 MathJax 渲染队列中。
如果 window.MathJax 不存在,则函数直接返回,不进行后续操作。否则使用 window.MathJax.Hub.Queue() 方法将两个任务加入队列:
['Typeset', window.MathJax.Hub, document.getElementsByClassName(elementId)]:根据类名选择器,将该类下的数学公式进行排版和渲染。另一个根据ID选择器将该类下的数学公式进行排版和渲染。
最后使用 export default 导出一个对象,包含了 isMathjaxConfig 变量、initMathjaxConfig 函数和 MathQueue 函数,使得其他模块可以引入和使用这些功能。
2.渲染组件
<template>
<div class="latexDiv" v-html="'$$'+latex+'$$'" />
</template>
<script>
import MathJax from '@/mathjax.js'
export default {
name: 'TheLatex2Math',
props: { latex: { type: String, default: '' }},
watch: { // 监视latex的变化
latex() {
this.mathJax()
}
}, // 限制父子组件参数为String
created() { // 组件刚创建的时候,watch并不会被触发,因为latex值没发生变化
this.mathJax()
},
methods: {
mathJax () {
this.$nextTick(function () { // Vue的DOM渲染是异步的
if (MathJax.isMathjaxConfig) { // 是否配置MathJax
MathJax.initMathjaxConfig()
}
MathJax.MathQueue('latexDiv') // 渲染对应的id/class
})
}
}
}
</script>
<style >
</style>
v-html
v-html="'$$' + latex + '$$'"
: 使用 Vue 的 v-html
指令,将 latex
属性中的字符串作为 HTML 解析并插入到 <div>
中。$$
是 LaTeX 公式的开始和结束标记,用于告诉 MathJax 解析器如何定位和渲染 LaTeX 公式。
Watcher 和 Created 钩子
-
watch
: Vue 的监视属性,监视latex
属性的变化。当latex
属性发生变化时,触发mathJax()
方法重新渲染公式。 -
created()
: Vue 实例创建时调用的钩子函数。在组件初始化时就调用mathJax()
方法,确保在页面加载时就渲染初始的 LaTeX 公式。
Methods 方法
-
mathJax()
: 自定义方法,用于调用 MathJax 来渲染 LaTeX 公式。-
this.$nextTick()
: 等待 Vue 更新 DOM 后执行回调函数。因为 Vue 的 DOM 更新是异步的,需要确保在 DOM 更新完成后再执行 MathJax 的渲染操作。 -
if (MathJax.isMathjaxConfig) { MathJax.initMathjaxConfig() }
: 检查 MathJax 是否已经配置,如果没有配置,则调用initMathjaxConfig()
来进行初始化配置。 -
MathJax.MathQueue('latexDiv')
: 将 ID 或者 Class 名称(在此例中是latexDiv
)传递给 MathJax,告诉它在该元素中渲染 LaTeX 公式。
-