delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

Djangoのテンプレート上でVue.jsを使う際のはまりどころ

概要

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で説明する。

  1. Vue.js側のMustacheの記法を変更する。
  2. 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: ["${", "}"] });