2
1

More than 3 years have passed since last update.

#2 Rails × Vue.jsで動的なページをSPAさせる

Last updated at Posted at 2021-08-07

前回
json形式でrailsからデータを引っ張ることができたので、その引っ張ってきたデータをもとに
Vue.jsのほうにフロント部分を記述できればいいなと思っています。

https://www.techpit.jp/courses/123/curriculums/126/sections/935/parts/3581
今回もこの教材を参考にしています。
著作権に引っかからないように、このコードの部分を自分の実装したいコードに落とし込んで説明していきます。

Vue.jsを書いていく

app/javascript/app.vue


<template>

</template>

<script>
import axios from 'axios';

export default {
  methods: {
    setDrink: function(){
      axios.get('/api/user/:id')
        .then(response => (
          this.drinks = response.data
        ))
    }
  }
}
</script>

こんな感じで書いていきます。

import axios from 'axios';

と書くことにより、axiosというモジュールをインポートしています。
axiosが非同期通信で必要と言うことでしたが、具体的にどういったときに必要なのかいまいち理解できていません。が一旦先に進みましょう。

export default {
  methods: {
    setDrink: function(){
      axios.get('/api/user/:id')
        .then(response => (
          this.drinks = response.data
        ))
    }
  }
}

上記のコードではsetDrinkという関数を定義しています。

axios.get('/api/user/:id')

というコードでは、APIを呼び出しています。
.getはHTTP動詞のgetです。

    .then(response => (
      this.drinks = response.data
    ))

.then()で通信が成功したときに行う処理を書きます。

通信できたら、/api/user/:idにアクセスしたときのレスポンスのデータを
this.drinksに代入します。

drinksをまだ定義してないので、それを定義しましょう

  data: function (){
    return{
      drinks: "drinks"
    }
  },
  methods: { ,,,,,,

dataではそのファイルで保持しときたいデータを定義します。

今回は、特定のユーザーのコーヒーの投稿のデータをdrinksプロパティに格納しておきます。

これでaxiosを使って、特定のユーザーのコーヒーの投稿のデータを呼び出すメソッドを記載しましたが、
そのメソッドがどういったときに呼ばれるのかを書く必要があります。

export default {
  data: function (){
    return{
      drinks: "drinks"
    }
  },
  mounted () {
    this.setDrink();
  },
  methods: {
    setDrink: function(){
      axios.get('/api/user/:id')
        .then(response => (
          this.drinks = response.data
        ))
    }
  }
}

mounted () {
this.setDrink();
},

と書くことにより、app.vueファイルが読み込まれた時点でsetDrink関数が呼び込まれます。

取得したデータをビューに表示

<template>
<ul>
  <li v-for="drink in Drinks" :key="drink.id">
    {{drink.name}}
    {{drink.price}}
  </li>
</ul>
</template>

一旦drinkのnameとpriceだけを表示させることにします。

v-forとは、each文みたいな感じで、drinksという配列を一つ一つ取り出して、ローカル変数drinkが配列の
要素一つ一つなのです。

users/show.html.erb

<%= javascript_pack_tag 'hello_vue' %>

と記述して、うまいこと呼び出してるつもりだけど、、、。

http://localhost:3000/users/7
にアクセスしたときに、

xhr.js:175 GET http://localhost:3000/api/users/:id 404 (Not Found)

Property or method "Drinks" is not defined on the instance but referenced during render.

とかなっていて、うまくいっていない

ではなく

だった。。

あとは、 axios.get('/api/users/7')
に書き換えたらうまくいくが

  axios.get('/api/users/:id')

だと上手くいかない。。。

んーー、やっかいなことになった。。。
これは長丁場になるぞ。。。。
あまりにも無理だったらパラメーターを指定しなくていいページのSPAも考えていく。

idパラメーターの扱いがやっかい。。。

まず、整理すると、

localhost:3000/users/7にリクエストが来る

users#showの処理が動く

処理の結果生成されたビューが表示

そのビューの中に、
<%= javascript_pack_tag 'hello_vue' %>
がある

hello_vueが表示

hello_vue.js ファイルを介してjavascript/packs/app.vueファイルを読み込みます。


app.vueが読み込まれる

よみこまれた瞬間setDrinks()が呼び出されて、
axios.get('/api/users/:id')
とサーバーにgetリクエストを送る。

まず、さーてどうしようかなー。

現在のURLを取得できればなんとか行けそう?

this.$route.path
で現在のurlが取得できるらしい。
なんか無理だった。

document.URLはjsのメソッドなので、いけるかなーーーー

console.log(document.URL);
vueファイルのscript部分に書いたらいけた。

しっかりと現在のパスが取得できた。
ただ、やりたいことは
axios.get('/api/users/:id')
これなので、どうしたものか。

console.log(location.pathname);

で、users/7が取得できた!
これでどんなユーザーでもそのユーザーの投稿が見れるはず!

  axios.get('/api' + location.pathname)

と書いた!!

したら、

スクリーンショット 2021-08-07 15.44.29.png

キターーーーーー!!!!!

めっちゃ部屋で叫んだwwwwwwwwwwwww
これは嬉しすぎるwwwwwww

わかりずらいですが
aaaa 3000
dddd 3000
とかが、コーヒーの名前と値段です
それらが取得できてるので、他にもコーヒーのexplainとかも取得できるでしょう!
よしやっとここからrailsからjson形式で取得したデータをもとにvueを書けるぞ!

だがしかし、画像はしっかりrailsから拾えるのか、、、
{{drink.image}}とやれば画像が表示されると思った自分が甘かった。。。。

この記事を参考に色々やっていこう。

いいね!!明日やっていく!

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1