I'm building a vue application and I want to use MathJax to render equations. I can get the equations to render when the component is mounted but I can't get the equations to rerender at a later point.
I made a code sandbox example to demonstrate this. Try to change the latex equation in the input and nothing changes even though the console shows the watcher is running.
Can someone please explain to me what I am doing wrong?
I added mathjax via cdn in the head of index.html with the following config
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'],['\\(','\\)']],
}
});
</script>
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_CHTML"></script>
and here is the code in my app component
<template>
<div id="app">
<input v-model="latex"/><br>
<div>{{latex}}</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
latex: '$$\\frac{a}{b}$$'
}
},
methods: {
reRender() {
if(window.MathJax) {
console.log('rendering mathjax');
window.MathJax.Hub.Queue(["Typeset", window.MathJax.Hub], () => console.log('done'));
}
}
},
mounted() {
this.reRender();
},
watch: {
latex: function() {
console.log('data changed')
this.reRender();
}
}
};
</script>
I am able to make it work by adding 2 things.
https://codesandbox.io/s/x2mlq38m4z
add key
to the div. key
is an indicator for virtual DOM. When key
is the same, Vue may reuse the same div element. When key
change, Vue will render a completely new DOM element, which is helpful when you want to apply 3rd party library's code (MathJax) to the DOM from scratch.
<div :key="latex">{{latex}}</div>
use $nextTick so that the rerender happens after the DOM have updated.
like this
watch: {
latex: function() {
console.log('data changed');
this.$nextTick().then(()=>{
this.reRender();
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With