2
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RailsのViewからVue.jsのModalを表示させてみた

Posted at

画像のように、一覧画面で詳細を開くボタンで詳細画面を開くときに、Railsのviewは使用せずVue.jsのModalで表示することを試みた。
何とか実装出来たが、JSはjQueryから入門したこともあり結構大変だったのでメモとして残しておく。
スクリーンショット 2020-03-10 19.41.40.png

環境

Ruby 2.6.5
Ruby on Rails 6.0.0
Vue.js 2.6.11

ここではRailsやVueの設定は省略し、Railsのwebpackerでvueのインストール、セットアップが完了していることを前提として書いていく。

やりたい事

冒頭の通り、詳細を開くボタンをクリックしたときに詳細画面をVue.jsのModalで開きたい。
しかし、今までRailsの中でVueを使った事はあっても、Vueインスタンスがどのタイミングで生成されるかなど無知であったため、最初はどうやるのかイメージがつかなかった。
jQueryからJavascriptに入門したので、なかなか生のJSを書く機会がなかった。

Rails側

Modalを開く部分はBootstrapを使うことにした。
参照: https://getbootstrap.com/docs/4.0/components/modal/

上記のURLを参考にして、BootstrapだけでModalを開けるようにしていく。

view/users/index.html.slim

thead
  tr
    th id
    th 名前
    th email
    th tell
    th
tbody
  - @users.each do |user|
    tr
      th = user.id
      td = user.name
      td = user.email
      td = user.tell
      td 
        / Vue側にuser_idを渡すために、data属性にuser_idを持たせている
        button.btn.btn-info.btn-modal data-target="#full-width-modal" data-toggle="modal" data-user_id="#{user.id}" 詳細を開く

/ Modalのコンポーネント部分。ここにVueのtemplateをマウントさせる。
#full-width-modal.modal.fade tabindex="-1" role="dialog" aria-hidden="true" aria-labelledby="full-width-modalLabel" data-keyboard="false" data-backdrop="static"
  #showUser
    = javascript_pack_tag 'users'

Vue.js側

次にvueインスタンスを生成させていく。
javascript/packs配下にusers.jsを作成し、コードを記述


javascript/packs/users.js

import Vue from 'vue'
// packs配下にcomponentsディレクトリを作成し、その中にcomponentを格納している
import ShowUser from './components/ShowUser.vue'

// ボタン要素をgetElementsByClassNameで配列として取得
const btnModals = document.getElementsByClassName('btn-modal')

// for文で各ボタン要素を取り出し
for(let btnModal of btnModals) {
  // 取り出したボタン要素に対し、addEventListenerでボタンクリックされた時にvueインスタンスを生成させる
  btnModal.addEventListener('click', () => {
    new Vue({
      el: '#showUser',
      render: h => h(
        ShowUser, {
          // componentにpropsでuser_idを渡している
          props: {
            userId: Number(btnModal.getAttribute('data-user_id'))
          } 
        }
      )
    })
  })
}

ここまで出来たら、あとはShowUser.vueを書いていけば終わり。
Modalを閉じるときはどうすればいいの?となりそうだが、単純に閉じるボタンのアクションにthis.$destroy()を仕込んであげれば大丈夫。
modalを閉じる処理をbootstrapのjQueryではなく、Vue側で書いてあげないといけないので、そこも含めて次回の記事で頑張って書いていく。

2
5
0

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
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?