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

  • 95
    Like
  • 0
    Comment
More than 1 year has 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

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