最近Vue.jsを勉強しはじめて、
なんとかRuby on Railsで書いた既存アプリのフロント周りをなんとかVue.jsで書き直してみたので自分用メモとして残しておきます。
#今回の目標
画像のようにECサイト上でジャンル一覧から任意のジャンルをクリックすると、
RailsのDBから呼び出されたジャンルごとのアーティストが描画されるようにする!
#概要
どうやってこれを実装するのか
RailsのデータベースをVue.jsで受け取るにはそのまま変数で渡すことはもちろん出来ません。
なので、RailsでAPIを作ってaxiosのgetメソッドでそこを叩いてVue側で受け取ることで繋がります。
#まずVue.jsの導入
今回は既存のRailsアプリに後からVueを入れるやり方です。
Gemfileに
gem "webpacker", github: "rails/webpacker”
を追記してbundle installします。
そしてターミナルで以下のコマンドを
$ bin/rails webpacker:install
##コンパイル
$ bin/webpack
でコンパイルしておきましょう
コンパイルが失敗したときは
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const environment = require('./environment')
module.exports = Object.assign({}, environment.toWebpackConfig(), {
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
})
をapp/config/development.rbに追記してください。
ここまででapp/javascript/packsというディレクトリが出来ているはずです。
今回はhello_vue.jsというファイルにコードを追記していきます。
##Vueを読み込みましょう
application.html.erbのyieldの下に
を追加
<%= javascript_pack_tag "hello_vue" %>
##APIの作成
今回hジャンルが選択されたら、そのジャンルのアーティストを配列で返すということをやりたいので、
Rails側のデータベースと連携させる必要があります。
なので
$ bundle exec rails g controller api::genres show
としてまずコントローラを作りましょう
#ルーティングの追記
namespace :api do
resources :genres, only: %i(show)
end
##API::GenresController
class GenresController < ApplicationController
def show
@genre = Genre.find(params[:id])
@artists = Artist.where(genre_id: params[:id])
end
end
ちなみにジャンルは複数のアーティストを持つので、
アソシエーションはGenre has_many artistsとなってます!
また、今回json形式で渡す必要があるのでjbuilderを使います。
app/views/api/genres/show.json.jbuilderに
json.genre_name @genre.genre_name
json.array do
json.array! @genre.artists, :artist_name, :id
end
として、ジャンルごとのアーティスト一覧をarrayで渡しています。
##APIの確認
/api/genres/1にアクセスすると
このようになっています。
ジャンルをクリックするたびにapi::genres_controllerが呼ばれて、クリックされたIDのジャンルがパラメータとして渡されています。
準備は整いました。
#Vue.jsを書いていこう!
##Vueのコード(hello_vue.js)
import Vue from 'vue/dist/vue.esm'
import axios from 'axios'
new Vue({
el: ".genre_vue",
data: {
genreInfo: {},
artists: [],
showModal: false,
},
methods: {
setGenreInfo(id){
axios.get(`api/genres/${id}.json`)
.then(res => {
this.genreInfo = res.data;
this.artists = res.data.array;
this.showModal = true
});
},
setArtistInfo(id){
window.location.href = `artists/${id}`;
}
}
});
RailsのAPIからデータを持ってくるために冒頭でaxiosをimportしてます。
まずdataの中でartistsを空の配列で用意します。
axiosで自作APIからgenre別のartist配列を持ってきて、this.artistsに格納します。
setArtistInfoは無理やりアーティスト詳細ページにリンクを繋げたかっただけでもっといいやり方があるはずです。。
##Railsのコード
<li v-for="artist in artists" v-on:click="setArtistInfo(artist.id)" class= "lime" v-bind:key="artist">
{{ artist.artist_name }}
</li>
先ほどVueの方でthis.artistsに格納された値をv-forディレクティブで回して
アーティストのアーティスト名をループさせています。
##完成です!
次は検索機能を実装していきたいと思います。
現在は検索したらページ遷移させているのVueを用いて非同期で検索結果をレンダリングさせるようにします。
#参照元
https://qiita.com/jnchito/items/30ab14ebf29b945559f6
https://qiita.com/cohki0305/items/582c0f5ed0750e60c951
https://qiita.com/cohki0305/items/a678b0b17c5b496c1de9