【Vue.js】vue-routerとmathjaxを掛け合わせてみたら数式が変換されていなかった話
携帯にいつのまにか書いた2018年の目標に週1でブログを更新するという項目があったため今週も書きました(使命感)
最近技術記事書いてなかったし、ちょうど苦しめられたことがあったので備忘録をば
概要
vue-routerを使ってSPAチックなWebアプリを開発していて、コンポーネント内にmathjaxで数式を変換して表示するような箇所がありましたがvue-routerでコンポーネントをレンダリングした箇所が数式を変換していないという問題が発生しました。。。
普通に画面遷移で作っていたときは変換されていたので完全に見落としてました。。。
再現
vue-cliでvueプロジェクトを作成
$ vue init webpack mathjax-test
index.htmlにmathjaxのCDNを配置する
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>mathjax-test</title> </head> <body> <div id="app"></div> <!-- 以下を追記 --> <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_CHTML"></script> </body> </html>
ひとまず数式が表示されるか確認するためにsrc/App.vue
に数式を設置してnpm run dev
を実行
<template> <div id="app"> $$ \begin{eqnarray} \sum^n_{k=1}a_k = S_n = a_1 + a_2 + ....+a_n \end{eqnarray} $$ </div> </template>
$ npm run dev
いい感じに表示されます。
vue-routerを使ってクライアントサイドルーティングを実装する。
とりあえずコンポーネントを二つ作ってみる。
src/components
配下にFormula1.vueとFormula2.vueを作成します。
<!-- Formula1.vue --> <template> <div id="formula1"> $$ \begin{eqnarray} \sum^n_{k=1}a_k = S_n = a_1 + a_2 + ....+a_n \end{eqnarray} $$ </div> </template> <script> </script>
Formula2は適当に数式を変えて作成してください。
コンポーネントを作成したらrouterの設定を行います。
import Vue from 'vue' import Router from 'vue-router' import Formula1 from '@/components/Formula1' import Formula2 from '@/components/Formula2' Vue.use(Router) export default new Router({ routes: [ { path: '/formula1', component: Formula1 }, { path: '/formula2', component: Formula2 } ] })
とりあえず/formula1
、/formula2
というルーティングを作成して、リンクをクリックしたらそれぞれのコンポーネントを表示するようにします。
src/App.vue
を以下のように書き換えます。
<template> <div id="app"> <div class="links"> <router-link to="/formula1">数式1</router-link> <router-link to="/formula2">数式2</router-link> </div> <router-view></router-view> </div> </template>
vue-routerの書き方に沿ってリンクとコンポーネントの表示場所を作成します。
そして数式1
をクリックしてみると。。。
mathjaxが効いていない!!!/(^O^)\ナンテコッタ
普通に画面をレンダリングした時には効いていたのに、一体なんなのかと。。。
とりあえずmountedのタイミングでmathjaxを読み込むように修正
src/components/Formula1.vue
のscriptsにを追記
export default { mounted() { MathJax.Hub.Queue(["Typeset", MathJax.Hub]); }, }
これで表示されるんとちゃいます?と数式1
をクリックしたら数式が表示されました。
mathjaxを利用しつつvue-routerを使う場合は数式が入ってくるであろうvueコンポーネントのmounted
のタイミングでmathjaxを読み込ませる必要があるようです。
createdのタイミングでは変換されず。。。
もしmathjaxとvue-routerを掛け合わせる時にはまっている人がいたら参考にどうぞ。。。
今回のソースコードも一応上げておきます。
https://github.com/kimuray/sandbox-vue-router-mathjax
最後に
これ実際に仕事ではめられた悲しみなんですが、仕事でやっていたときはmountedで読み込ませるだけでもダメで、createdのタイミングでも読み込ませるという二段構えをしないと数式が変換されませんでした。。。
仕事の環境はvue.js + Rails(しかも変換箇所はマークダウンで記載されている)みたいな感じだったのが何か影響していたのかなあ。。。
もしmountedにmathjax設定しても動かない場合はcreatedにもmountedと同じ記載をすれば動くかもしれないのでおためしあれ。。。