動作検証した各ライブラリバージョン
- Rails : 4系(5系でも問題なく動きそう)
- Vue.js : 2.5.13
注意
サンプルコードは実際のコードを抽象化したものであるため雑に抽象化されて分かりにくいかもしれません
想定されるアプリの構成
gem 'webpacker'
を使用してRails上でVue.jsを動かしているアプリケーション- Vueコンポーネントはerbに埋め込む形で使用しており、Railsと密結合な中でVue.jsを使う場合
erbからVueコンポーネントに値を渡したい場合の例
- 会員登録時に送信されるアクティベーションメールに記載されたリンクをクリックするとGETでユーザーのアクティベーションのアクションが呼ばれる
- そのアクションでは個人情報入力フォーム用テンプレートの描画を行う必要がある
render テンプレート名
をする一方で任意の値をVueフォームコンポーネントに渡したい
この場合に問題になること
以下にサーバーサイドの実装サンプルを記載
hoges_controller.rb
# 会員アクティベーション用のメールに記載されたアクティベーションのリンクをクリックした後に呼ばれるアクションだと仮定 # GETでアクセスしてくる def activate # 何らかの処理 # hoge.html.erb を hoge というlayoutファイル上で表示したい # localeでerbにサーバーサイドの値を渡す render 'hoge', layout: 'hoge', locals: { user_name: user_name } end
ここでネックになるのが、render json: { key: value }
ならVueコンポーネント上で直接投げられた値に this
でアクセス出来るが今回は render json
で値を渡せないこと。
今回やることの大まかな流れ
- コントローラーからlocalsでerbに値を渡す
- サーバー側で渡した値をerbからVueコンポーネントに渡す
- Vueでerbの値を受け取る
1. コントローラーからlocaleでerbに値を渡す(Rails側)
- サーバーサイドからlocale経由でerbへ値を渡す
hoges_controller.rb
# 会員アクティベーション用のメールに記載されたアクティベーションのリンクをクリックした後に呼ばれるアクションだと仮定 # GETでアクセスしてくる def activate # 何らかの処理 # hoge.html.erb を hoge というlayoutファイル上で表示したい # localeでerbにサーバーサイドの値を渡す render 'hoge', layout: 'hoge', locals: { user_name: user_name } end
2. サーバー側で渡した値をerbからVueコンポーネントに渡す(Rails側)
hoge.html.erb
<div> <hoge-form user_name="<%= user_name %>"></hoge-form> </div>
3. Vueでerbの値を受け取る(Vue.js側)
- erbから受け取った値をデフォルトでコンポーネント描画時に表示したいという想定
- propsでerbから受け取りたい値を定義しておく
- propsに記載した値はdataプロパティには改めて定義しなくて良い
HogeForm.vue
<template> <div class="user_name"> // ここでpropsで定義した値を受け取って描画出来る {{ user_name }} </div> <dl class="form_mail"> <dt class="input_title">メールアドレス</dt> <dd class="input_mail"> <input v-model="email" type="email" placeholder="sample@sample.jp" > </dd> </dl> <dl class="form_password"> <dt class="input_title">パスワード</dt> <dd class="input_password"> <input v-model="password" type="password" placeholder="password" > </dd> </dl> <div class="register_button"> <button class="btn btn_send_long" @click="onSubmit" >登録 </button> </div> </template> <script> export default { props: { // 今回大事なのはここ!propsでerbから受け取る値を定義しておくこと // typeでStringを指定しておくことで文字列以外をエラーに出来る user_name: { type: String, default: null } }, data: function () { return { // 任意のプロパティ email: '', password: '' }; }, methods: { // 任意のfunction async onSubmit () { // 何らかの処理 } } }; </script>
これでサーバーサイドの値をerb経由でVueコンポーネントに渡すことが出来ます!