概要
Djangoのテンプレート上でVueを使う方法について書く。
※ 尚、本記事はDjangoのテンプレートをテーマにしているが、サーバーサイドのテンプレートエンジンとVue.jsを両方使う場合に汎用的な話だと思う。
何も気にせずに、Djangoのテンプレート上にVue.jsを書くと、Djangoのテンプレートの記法とVue.jsのMustacheの記法がバッティングしてしまい、Vue.jsが意図した挙動をしないという問題がある。
具体的には、以下の記法がバッティングしている。
・Djangoのテンプレートで変数名を表示する方法
{{ user.username }}
・Vue.jsのMustacheで変数名を表示する方法
{{ hoge }}
従って、Vue.js側で変数名「hoge」を表示したいと思って、上記のように書いても先にサーバーサイド側で空文字に変換されてしまい、意図した挙動にならない。
上記の問題を解消する方法を以下の2stepで説明する。
- Vue.js側のMustacheの記法を変更する。
- 1の設定をComponentごとに入れずに一括で設定する。
この問題にはまって調べていた時、1についてはけっこう記事が見つかったが、2まで言及している記事が見つからなかった。
結論
以下の1行を宣言する。
Vue.mixin({ delimiters: ["${", "}"] });
※ 記法は${変数名}じゃなくてもよい。
結論に到る経緯
1.Vue.js側のMustacheの記法を変更する。
まずはVue.js側のMustacheの記法を{{変数名}}
から${変数名}
変更する。
これはWEB上に既にナレッジがけっこう存在しており、Vueインスタンスに以下のように設定すればよい。
new Vue({ // ... delimiters: ["${", "}"], // ... });
ただし、Componentを使用していない場合は↑の設定だけでよいが、Componentを使用している場合は、親に設定した「delimiters」が子Componentに伝播しないという問題がある。
従って、愚直にやるなら各Componentごとに以下の宣言を書く必要がある。
Vue.component("sample", { // ... delimiters: ["${", "}"], // ... }); });
が、これはDRY原則に反するし、Component数が増えてくると面倒くさい。
2.1の設定をComponentごとに入れずに一括で設定する。
「delimiters」の宣言を一箇所にできないか調べていたところ、以下のstackoverflowのQAを見つけた。
stackoverflow.com
この回答に従い、以下のようにmixinを使って書くと、1行で全てのComponentに「delimiters」を設定することができた。
Vue.mixin({ delimiters: ["${", "}"] });