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>