Madogiwa Blog

主に技術系の学習メモに使っていきます。

railsのViewからVueの単一ファイルコンポーネントへモデルのインスタンスを受け渡すMEMO

railsのviewからVueの単一ファイルコンポーネントへモデルのインスタンスをいい感じに渡す方法を模索して、結構ハマってたのですが、自分なりに落ち着いたのでやり方をメモしておきます✍

今回やりたかったこと

やりたかったのは、下記のようにモデルのインスタンスの配列を、そのまま単一ファイルコンポーネントと渡すということがやりたかった。

しかし、viewから単一ファイルコンポーネントへ行くと、railsの世界から離れてしまうので、いい感じに渡す方法がイマイチ思いつかなかった。。。 ※ネットで調べるとviews側にscriptタグ使ってVueのinstanceを生成するとかも書いてあったけど、いまいちな気がしてしまい。。。

<div class="feed-show" id="feeds-entries">
  <h1 class="title"><%= @feed.title %></h1>
  <entry-card-collection entries="<%= @entries %>"></entry-card-collection>
</div>
<%= javascript_pack_tag 'feeds' %>
class FeedsController < ApplicationController
  def show
    @feed = Feed.find(params[:id])
    @entries = @feed.entries.order(published_at: :desc)
  end
end

どうやったか

いろいろハマったけど、やった方法は下記です。

<div class="feed-show" id="feeds-entries">
  <h1 class="title"><%= @feed.title %></h1>
  <entry-card-collection :entries="<%= @entries.to_json %>"></entry-card-collection>
</div>
<%= javascript_pack_tag 'feeds' %>

ポイントは2つ。

  • v-bindで値を受け渡すこと
  • to_jsonしてjson形式で値を渡すこと

あとは、単一ファイルコンポーネント側でpropsを定義して普通に使えばOKです🙌 ※取得する際にJSON.parseする必要があるかなと思いましたが、しなくてもいい感じにデフォルトでParseしてくれるみたいですね🤔

<template>
<div class="entries">
  <entry-card
    v-for="entry in entries"
    :key="entry.id"
    :entry="entry">
  </entry-card>
</div>
</template>
<script>
import EntryCard from './EntryCard'

export default {
  name: 'EntryCardCollection',
  components: { EntryCard },
  props: ['entries']
}
</script>
<style lang="scss">
</style>

参考

www.reddit.com