Help us understand the problem. What is going on with this article?

ページの一部をVue.jsで作るときにバックエンドからVueインスタンスに値を渡す方法(csrfTokenの例)

導入

ページ全体ではなくてページの一部にVue.jsを導入することができますが、
一般的にVueインスタンスにバックエンド側から初期値を渡す場合に2通りの方法があると考えています。

  1. 一度JavaScriptファイルを配信して、そこからバックエンドAPI経由で値を取得する方法
  2. バックエンドから初期値を入れた状態のJavaScriptファイルを配信する

この記事では、このうちの2つ目の方法について紹介します。

やり方詳細

例としてバックエンド側からcsrfTokenを渡したいケースについて扱います。
以下のようなHTMLがあるとします。後述するように、ここで piyo-child-component が子コンポーネントを表します。

        // headタグ辺りで定義しておく。`{{ }}` は Laravel Blade の記法。`csrf_token()`はLaravelのヘルパ関数。これらは他のフレームワークでもバックエンド側でviewで入れられれば同じかと思います
        <meta name="csrf-token" content="{{ csrf_token() }}">

        // ここにVueインスタンスがマウントされる
        <div class="js-hogehoge">
            <piyo-child-component
                    :csrf-token="csrfToken"
            ></piyo-child-component>
        </div>

対応する JavaScript は以下のようになります。これはVueではなくて単なる素のJavaScriptで書かれています。

  import PiyoChildComponent from './components/piyo-child-component';

  // metaタグからバックエンドで生成したcsrfTokenを取得
  const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

  // 上記html内のclass属性からelementを取得
  const elementHogeHoge = document.querySelector('.js-hogehoge');
  if (elementHogeHoge) {
    // elで指定したDOMに無名Vueインスタンスをマウントする(htmlの上にVueインスタンスを乗っけるイメージ)
    new Vue({
      data() {
        return {
          csrfToken: csrfToken,
        };
      },
    // Vueインスタンスをマウントする先を指定 
      el: elementHogeHoge,
      // 通常のvueコンポーネントの中で他のコンポーネントを使用するときに書く記法と同じ
      components: {PiyoChildComponent},
    });
  }

以下のコードは再掲になりますが、上記JavaScriptの中でcomponentsで指定したPiyoChildComponentは、暗黙的にケバブケース(ハイフン続きで置き換えたもの)で呼び出しされます。

  • 注意: 完全にvueの世界に入ってしまえば :csrfToken="csrfToken" でも :csrf-token="csrfToken" でもどちらでも動くのですが、ここはまだhtmlの世界なので大文字小文字の区別がなく、キャメルケースでは動かないので注意が必要です。参考: https://jp.vuejs.org/v2/guide/components-props.html
            <piyo-child-component
            // 上記の data() で親である無名Vueインスタンスが受け取ったデータを、ここで子コンポーネントに渡しています
                    :csrf-token="csrfToken"
            ></piyo-child-component>

ここで渡した値は子コンポーネントの中でpropsとして受け取ることができます(通常のコンポーネント間での受け渡しと同じ)。

<script>
  export default {
    name: 'piyo-child-component',
    props: ['csrfRoot'],
  };
</script>

Special Thanks

この方法は同僚の @zackey2 さんに教えてもらいました。ありがとうございます!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away