Posted at

[Rails4] Vue.js の導入手順 & DBデータを表示する方法

More than 3 years have passed since last update.

Rails に、MVVM の JavaScript ライブラリである Vue.js を導入し、データベースの中身を表示するまでやってみます。


Vue.js は レガシーブラウザ(例:IE8系)は非対応なので注意ください。



前提


  • 手元の OS:Mac OS X 10.9.5 (Mavericks)

  • Ruby:2.1.2

  • Rails:4.1.1


環境構築


① Railsのプロジェクト作成

$ bundle exec rails new hoge_app --skip-bundle -T



  • テストは後々、Rspec を使いたいので -T を指定。

  • データベースはデフォルトの sqlite3 を今回は採用。



② Gemfileの編集

Vue.js だけを使うなら gem 'vuejs-rails' のみでいいのですが、最低限のデザインの為の Twitter Bootstrap、テンプレート用の Haml、あとはデバックで必要そうな gem も導入しておきます。


rails_angular_app/Gemfile

#..

gem 'vuejs-rails'
gem 'bootstrap-sass'
gem 'haml-rails'
gem 'erb2haml', group: :development

gem 'better_errors', group: :development
gem 'binding_of_caller', group: :development
gem 'pry-rails', group: :development

#..



③ Bundler で gem をインストール

$ cd hoge_app

$ bundle install --path vendor/bundle



  • インストールが終わったら一旦、ここで動作確認。ブラウザで http://127.0.0.1:3000 にアクセスし、お馴染みの画面が表示されればOK。

    $ cd hoge_app
    
    $ ./bin/rails s



④ Spring の有効化

とくに Vue.js とは関係ありませんが、やっておきます。

$ cd hoge_app

$ bundle exec spring binstub --all


⑤ Haml 関連の設定

既存の .erb ファイルを .haml ファイルへ変換。

$ cd hoge_app

$ ./bin/rake haml:replace_erbs


⑥ Vue.js 関連の設定



  • app/assets/javascripts/application.js に追記。


    app/assets/javascripts/application.js

    //= require vue






⑦ Twitter Bootstrap 関連の設定



  • app/assets/stylesheets/application.css.scss を新規に作成して編集。

    $ touch app/assets/stylesheets/application.css.scss
    


    app/assets/stylesheets/application.css.scss

    @import "bootstrap-sprockets";
    
    @import "bootstrap";


    行の順番を入れ替えると動かないかもなので注意。





  • 既存の app/assets/stylesheets/application.css は削除。

    $ rm app/assets/stylesheets/application.css
    



  • app/assets/javascripts/application.js に追記。


    app/assets/javascripts/application.js

    //= require bootstrap-sprockets






作った環境の動作確認


① とりあえず適当に Scaffold

$ ./bin/rails g scaffold person name:string age:integer memo:text

$ ./bin/rake db:migrate


② Bootstrap の動作確認



  • 共通ページレイアウトを修正。


    app/views/layouts/application.html.haml

    !!!
    
    %html
    %head
    %title HogeApp
    = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
    = javascript_include_tag 'application', 'data-turbolinks-track' => true
    = csrf_meta_tags
    %body
    %nav.navbar.navbar-default{role: "navigation"}
    .container-fluid
    .navbar-header
    %a.navbar-brand{href: "#"}
    home
    .container
    = yield




  • 表示を確認。

    $ ./bin/rails s
    

    ブラウザで http://127.0.0.1:3000/people にアクセス。

    screen2.png




③ Vue.js の動作確認


View


app/views/people/index.html.haml

#demo
%p
{{lastName}} {{firstName}}
%p
%input{"v-model" => "lastName"}/
%input{"v-model" => "firstName"}/

%br
%br

%p
{{message}}
%p
%button.btn.btn-primary{"v-on" => "click: execute"} 実行



Haml 記法です。



ViewModel


app/assets/javascripts/people.js.coffee

$ ->

demo = new Vue(
el: "#demo"
data:
firstName: "太郎"
lastName: "山田"
methods:
execute: ->
@message = "実行しました"
return
)

return


次のようにデータバインドが動いていればOK。

screen1.png


データベースの中身を Vue.js で描写してみる

Scaffold で作成した Person モデルのデータを、一覧ページ(:index)において Vue.js で描写してみます。


① Rails の View


app/views/people/index.html.haml

%h1 Listing people

#index

:coffee
rails = window.rails = window.rails ? {}
rails.objPeople= #{raw @people.to_json}

%table.table.table-striped
%thead
%tr
%th 名前
%th 年齢
%th メモ
%tbody{'v-repeat' => 'items'}
%tr
%td
{{name}}
%td
{{age}}
%td
{{memo}}
%P
%a{:href => '/people/new'} New Person


CoffeeScript 部分では、rails = window.rails = window.rails ? {} のようにして、この View 以外のファイルから参照できるよう、変数 rails をグローバルにエクスポートしています。

rails.objPeople= #{raw @people.to_json} により、Viewの出力時に Person モデルのデータの中身が JavaScript のオブジェクトへ代入されます。

.. Vue.js はすっきり書けていいですね^^


② Vue.js の ViewModel


app/assets/javascripts/people.js.coffee

$(document).on('ready page:load', ->

if $("#index")[0]
new Vue(
el: "#index"
data:
items: rails.objPeople
)

return
)


new Vue() により ViewModel を定義します。el プロパティによりバインド対象とする div エリアを指定、data プロパティでは、先程エクスポートした Person モデルのデータを 変数 items に紐づけます。


注意1

Rails の turbolinks 下で、この ViewModel を「初期読み込み時」「ページ遷移時」で動かすために次のようにしています。

$(document).on('ready page:load', ->


)

上記の page:load イベントは、純粋な jQuery のイベントではなく、turbolinks 用に拡張されたイベントです。


詳しくはこちら ⇒ https://github.com/rails/turbolinks



注意2

if $("#index")[0] のようにして、「id='index'のdivエリアが存在する」場合に限って ViewModel を作成するようにしています。これは Rails が、どの Controller であるかに関わらず app/assets/javascripts/ ディレクトリ下のファイル全てを読み込んでしまうため、ほかの View 用の ViewModel を読み込んだ場合に div エリアが存在しない旨の JavaScript エラーが出てしまうからです。


③ 動作確認

Vue.js で描写できました^^

スクリーンショット 2014-10-11 23.16.14.png

今回のソースは GitHub に置いておきます。手順通りやっても動かないぞ、という場合はこちらをご覧ください。

https://github.com/hkusu/Vue.js_Rails_seed


参考URL

といっても前に自分で書いたものですが..