👌

hugoとvuejsを組み合わせるときの{{ }}の衝突を回避する

2022/06/11に公開約2,600字

Hugo新入生です。VueはVue2時代から使っています。
さてHugoでWebサイトを構築したところまでは良かったのですが、サイトの全文検索で戸惑いました。
Vueに慣れており、バニラスクリプトは逆に苦手です。当然、サイトの全文検索にもVue.jsを使いたいと考えました。

すでにHugoとVue.jsを使って問い合わせフォームを作ったことは有りました。
成果物のページはこちらです
NipoPlus問い合わせフォーム
この問い合わせページ自体はhugoで作られています。
マークダウン形式のファイルにVueをインポートして、問い合わせフォームを実装しています。
ソースが気になる方は問い合わせフォームの画面右上にある「編集」ボタンをクリックすることでソースを見ることもできます。(Githubに公開しています)

shortcodeとして検索フォームを埋め込もうとしてエラー

さて、前述の問い合わせフォームは .mdファイル形式だったため、文中に{{}}を使っても特に問題は有りませんでした。しかしshortcodeは .htmlのため、hugo本来のgolangと競合してしまうようでした。
(間違っていたらすみません。)

<div id="q-app">
  <div>めっせーじ {{ msg }}</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@2.7.1/dist/quasar.umd.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@2.7.1/dist/lang/ja.umd.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script> 
<script>
  // 検索フォーム
  const app = Vue.createApp({
    setup () {
      const msg = Vue.ref('とりあえずうごかしてみる')

      return {
        msg
      }
    }
  })
  app.use(Quasar)
  Quasar.lang.set(Quasar.lang.ja)
  app.mount('#q-app')
</script>

純粋なVue.jsではなく私はQuasarフレームワークを使用していますので、初期化周りが純正のVueとは少し違いますが、誤差の範囲です。

さて、このように書いくとエラーが吐き出されます

parse failed function "msg" not defined 
<div id="q-app">
  <div>めっせーじ {{ msg }}</div> // この行がハイライトされている
</div>

hugoも{{}}をつかうし、Vue.jsも{{}}を使うことが原因です。

Vue.jsの{{}}を[[]]に修正すればOk

先に回答

<div id="q-app">
  <div>めっせーじ [[msg]]</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@2.7.1/dist/quasar.umd.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@2.7.1/dist/lang/ja.umd.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"></script> 
<script>
  // 検索フォーム
  const app = Vue.createApp({
    delimiters: ["[[", "]]"],
    setup () {
      const msg = Vue.ref('とりあえずうごかしてみる')

      return {
        msg
      }
    }
  })
  app.use(Quasar)
  Quasar.lang.set(Quasar.lang.ja)
  app.mount('#q-app')
</script>

こんなときにもVue.jsは使えるのがすごいです。ポイントは

delimiters: ["[[", "]]"],

ですね。この命令により {{}}が [[]]として使えるようになります。
普段からVue cliなどを使っている方はまず使う機会が無いのではないでしょうか?わたしも初めて知りました。感動したのでここに筆を取った次第です

Discussion

ログインするとコメントできます