概要
stimulus.js × view-componentの導入を学んだので、
記録のために残しておきます。
今回のゴールは stimulus.js × view-component で
以下の入力欄に文字を入力し、Greetを押すと、横に「Hello, 〇〇!」と表示されたら成功です。
↓↓↓
参考資料
stimulus公式ドキュメント
[viewcomponent公式ドキュメント]
(https://viewcomponent.org/guide/getting-started.html)
環境
・Mac M1 バージョン11.4
・Ruby 2.6.8
・Rails 6.1.4.1
手順① アプリを作成
まずは以下のコマンドで新しくファイルを作成します。
% rails new stimulus-view-component
これで必要なファイルがインストールされました。
手順② stimulusをインストール
以下のURLを参考にstimulusのインストール方法を確認します。
https://github.com/hotwired/stimulus-rails
まずはgemfileに以下を記述します。
gem 'stimulus-rails'
続いて以下のコマンドを順番に実行します。
% ./bin/bundle install.
% ./bin/rails stimulus:install
stimulusはインストールは完了しましたが、
You must import "./controllers" in your JavaScript entrypoint
私の環境では、赤字でこのようなエラーが出ました。
**「"./controllers"」**の設定をしてあげる必要があるため、
app/javascript/packs/application.js に
**「import "controllers"」**を追記します。
以下の通りです。
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
Rails.start()
Turbolinks.start()
ActiveStorage.start()
import "controllers" // ← これを追記
これでstimulusのインストールが完了しました。
次にview-componentをインストールしていきます。
手順③ view-componentのインストール
view-component の公式ドキュメントを参考にしながらインストールしていきます。
[https://viewcomponent.org/guide/getting-started.html]
(https://viewcomponent.org/guide/getting-started.html)
最初に、view_componentのgemをgemfileに追記します。
gem "view_component", require: "view_component/engine"
% bundle install
これでインストールが完了しました。
現時点でうまく反映できているか確認するため、
サーバーを動かします。
% rails s
http://localhost:3000/で確認します。
手順④componentファイルの作成
以下のコマンドでcomponentファイルを作成します。
% bin/rails generate component Example title
作成されたファイルの中のapp/components/example_component.rb が
以下の画像と同じになっているか確認して下さい。
確認できたら、今度はapp/components/example_component.html.erb
を以下のように変更します。
<span title="<%= @title %>"><%= content %></span>
手順⑤ viewファイルの作成
view配下に
app/views/home/index.html.erb を作成します。
これでviewファイルが作成できたので、公式ドキュメント通りに以下の記述を加えていきます。
<%= render(ExampleComponent.new(title: "my title")) do %>
Hello, World!
<% end %>
手順⑥ stimulusファイル作成
手順①で生成されたファイルの中のapp/assets/javascripts/controllers/hello_controller.jsを
下記のように書き換えます。
// app/assets/javascripts/controllers/hello_controller.js
import { Controller } from "@hotwired/stimulus"
// Connects with data-controller="hello"
export default class extends Controller {
static targets = [ "name", "output" ]
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
}
}
さらにapp/views/home/index.html.erbに
以下を追加します。
<%= render(ExampleComponent.new(title: "my title")) do %>
Hello, World!
<% end %>
↓下記を追記↓
<div data-controller="hello">
<input data-hello-target="name" type="text">
<button data-action="click->hello#greet">
Greet
</button>
<span data-hello-target="output">
</span>
</div>
これで公式ドキュメントを参考にした、セットアップは終了です。
動くか確かめてみましょう。
しかし、これではまだ動きません。
ルーティングとコントローラーを設定していませんでした。
それぞれ設定していきます。
Rails.application.routes.draw do
root 'home#index' # こちらを追記
end
これでルーティングの設定は完了です。
続いてコントローラーを設定していきます。
% rails g controller home
作成されたコントローラーに以下を記述します。
class HomeController < ApplicationController
def index # こちらを追記
end
end
ルーティングとコントローラーを設定が完了したのでサーバーを動かしていきます。
% rails s
http://localhost:3000/で確認します。
上手くいきました!!
「Qitta」と入力すると
「Hello, Qiita!」
とstimulus.js × view-componentがうまく反映されてました。
追加実装
①component配下にまとめる
stimulus.js × view-component を動かすことができましたが、
今のままでは、componentに関するファイルがjavascriptやcomponentsファイルにバラバラに入っているので、今後さらに大きな実装をする際にどれがどのファイルか分かりづらくなってしまいます。
そのため、app/components/の次の配下にexampleを作成し、それぞれまとめていきます。
app/components/example/example_component.rb
app/components/example/example_component.html.erb
app/components/example/hello_controller.js
さらにこれらのファイルを分かりやすい名前に変えます。↓↓↓
app/components/example/component.rb
app/components/example/component.html.erb
app/components/example/component_controller.js
ファイル名を変えたので、それぞれのファイル内の記述も変更していきます。
ファイル内の記述の変更
# frozen_string_literal: true
class Example::Component < ViewComponent::Base
def initialize(title:)
@title = title
end
end
# ExampleComponentに「::」を追加
<span title="<%= @title %>"><%= content %></span>
# ↓↓下記を追記
<div data-controller="example--component">
<input data-example--component-target="name" type="text">
<button data-action="click->example--component#greet">
greet
</button>
<span data-example--component-target="output">
</span>
</div>
<%= render(Example::Component.new(title: "my title")) %>
# ↑↑↑ExampleComponentに「::」を追記↑↑↑
# ↓↓下記を削除↓↓
<div data-controller="hello">
<input data-hello-target="name" type="text">
<button data-action="click->hello#greet">
Greet
</button>
<span data-hello-target="output">
</span>
</div>
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "name", "output" ]
greet() {
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
}
}
これでそれぞれのファイルの書き換えは完了しました。
##Stimulusの書き方変更
続いてstimulusの公式ドキュメントを見ながら、
example階層にした際の書き方に変更していきます。
import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"
const application = Application.start()
const context = require.context("controllers", true, /\.js$/)
const contextComponents = require.context("../../components", true, /_controller\.js$/)
application.load(
definitionsFromContext(context).concat(
definitionsFromContext(contextComponents)
)
)
少し記述を変えていきます。
import { Application } from "@hotwired/stimulus"
import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers"
const application = Application.start()
const context = require.context("controllers", true, /\.js$/)
const contextComponents = require.context("../../components", true, /_controller\.js$/)
application.load(
definitionsFromContext(context).concat(
definitionsFromContext(contextComponents)
)
)
require.context("../../components", true, /_controller.js$/)
これによってcomponents配下のcontrollerを一斉に動かすことができるようになります。
**「@hotwired」**のエラーができる方は
package.jsonのファイルを書き換えて
yarn installを実行します。
# 下記を追記↓↓
"@hotwired/stimulus": "^3.0.0",
"@hotwired/stimulus-webpack-helpers": "^1.0.0",
% yarn install
これで@hotwiredに必要なものはインストールできました。
最後に下記を実行していきます。
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: ["app/components"]
# []に"app/components"を追記
これでexample階層を新しく作成し、componen配下をまとめることができました。
動くか確認します。
無事動きました!!
*動かない場合は、ターミナル上で**「command+R**」を押すことでスーパーリロードを実行し、
改善されるかもしれません。
###initialize()
一度、コントローラーが最初にインスタンス化されたときに呼び出される
###connect()
コントローラがDOMに接続されているときはいつでも呼び出される
###[name]TargetConnected(target: Element)
ターゲットがDOMに接続されているときはいつでも呼び出される
###disconnect()
コントローラがDOMから切断されたときはいつでも呼び出される
###[name]TargetDisconnected(target: Element)
ターゲットがDOMから切断されたときはいつでも呼び出される
最後に
stimulus.js × view-component は以上になります。
〇〇×〇〇やってみたシリーズは今後も学習するので、
都度、新しく投稿していきます。