SakuraWi - BLog

WEBエンジニア。聴いたお話をまとめておく倉庫的な。スタックストックスタック!

Rails2年目のさく氏による, stimulus試した実践ガイド


どうも! くふうカンパニーアドベントカレンダー、7日目担当の@KotaSakurawiです。

くふうのアドカレはこちらから▶︎くふうカンパニー Advent Calendar 2018 - Qiita

今日の記事は! フロント寄りの内容になります。Stimulusについて触る機会がありましたので、こんな感じに書いていくよ、という説明をします!

そもそもstimulusとは?

まずstimulusって何かということから書いて行きます。javascriptのフレームワークということくらいしか僕も知りませんでした。

ひとまずググって公式サイトをみてみましょう。なになにふむふむ。

Stimulus: A modest JavaScript framework for the HTML you already have.

GitHub - stimulusjs/stimulus: A modest JavaScript framework for the HTML you already have

A modest JavaScript framework for the HTML you already have.

訳: HTMLのための最もモダンなJavaScriptのフレームワーク。

なるほど(わからん)。モダンに書けるってことか!

stimulusはbasecampのメンバーによって開発されたJavaScriptのフレームワークで、特徴としてHTMLの変化をさせることに特化している印象が強いです。

Railsとの親和性が高く、とっつきやすいと聞いたこともあります。実際、自分も記述の形式にはあまり抵抗がなく使い始めることができました。

Basecamp: Project Management & Team Communication Software

早速使ってみよう

ということで触るのが一番!やってみましょう。

最初にstimulusを学習するには、、公式サイトにあるhandbookを一通りやってみて感触を掴んでいくのがいいと思います。

Stimulus Handbook: Introduction

今回はディレクトリの構成や環境の用意部分は割愛させていただきます。

ざっくりと構成

RailsはMVCモデルの考え方で開発されています。

stimulusも同様の考え方に近いと思っています。

DOM(オブジェクト)の取得をcontrollerで行なって、DOMのややこしい操作、ajaxなどの通信を行なったりするロジックをmodelに書くといった責務の切り分けができるようになります。

切り分けができると、jsに対するテストも記述がしやすくなりますよね。

特に、ユニットテストが書けるようになるのは保守性が高まって良いのでは!

前提として、これを踏まえておきましょう。

handbookをやっていくよ!

handbookの内容を引用しながら説明をしていこうと思います。

コードは基本的にhandbookからの引用とさせていただきます。

// src/controllers/hello_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    console.log("Hello, Stimulus!", this.element)
  }
}

これが基本的な書き方をしているjsのコントローラのファイルです。

このjsですと、 connect()はcontrollerが読み込まれた時に処理が走るようになります。initializeみたいな感じですね。

なるほどなるほど。じゃあこのcontrollerが読み込まれるようにするにはどうするのか、みて行きましょう。

簡単なhtmlの構成はこんな感じになります。

<div data-controller="hello">
  <input data-target="hello.name" type="text">
  <button data-action="click->hello#greet">Greet</button>
</div>

使いたいコンポーネントがある部分を囲えるように、一番外側にdata-controllerの属性を付与したタグを置きます。

これでどのcontrollerを使用するを指定します。 今回でいうと、hello_controllerが対象になるということですね。

stimulusは、data属性を使って紐づけていく、というのが基本です。

メソッドを呼び出していくぞ!

さて、ではメソッドを呼び出して処理させて行きましょう。

例えばボタンを押したら文字が切り替わる、その切り替えるメソッドをどう呼ぶのかという感じです。

先ほどのHTMLファイルのdata-targetや、data-actionが怪しいですよね。

ということで、jsファイルを少し拡張するとこんな感じに。

// src/controllers/hello_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name" ]

  greet() {
    const element = this.nameTarget
    const name = element.value
    console.log(`Hello, ${name}!`)
  }
}

static targets = [ "name" ]to,greet(), this.nameTargetの記述に注目していきます。

targetでコンポーネントを指定する

htmlのファイルでdata-targetの属性がついているコンポーネントは、操作対象のコンポーネントの指定になります。

<input data-target="hello.name" type="text">

たとえば、こちら。inputタグが使われているので、ユーザが入力したものを取得できそうです。

この入力したデータを、jsの方で扱うためにstimulusの記法にしたがってコードを追記します。

static targets = [ "name" ]this.nameTargetです。

ちなみに、複数のコンポーネントを操作する場合は、以下のようにします。

static targets = [ "name", "title" ]

このように定義しておくと、そのコンポーネントを呼び出す時にthis.xxxTargetと呼び出せるようになるのです!

jQueryでいうところの、$(".class_name")みたいなものです。

あとは、data属性に色々格納されていると this.nameTarget.dataset.xxxといった呼び出し方も可能です。

複数のターゲットを取得したりもできます。この時は、this.nameTargetsのように書けます。

Stimulus Reference: Targets

actionでメソッドを呼び出す

次に、data-actionで指定したものについて説明します。

<button data-action="click->hello#greet">Greet</button>

のように、data-actionでcontrollerとメソッドを指定します。

メソッドが呼ばれるタイミングはclick->といったものを記述することで、クリックの時に、hello_controllerの greet()が呼ばれます。

modelにjsファイルを追加する

以上の内容はcontrollerの中で完結する処理ですが、modelを作って責務を切り分けていくケースもあると思います。

その時は、それぞれのアプリのディレクトリ構成によりますが、packs/controllerの中にcontroller関連のファイルを置き、packs/models配下にmodelファイルを追加していきます。

その際、各コントローラーから使用する時は、controllerの上部にこのような記述で読み込みを行いましょう。

import CalcTax from '../models/calc_tax

...

   def connect() {
     CalcTax.calculate(300, japan)
   }

などなど。ちょっと命名が悪いかもしれませんが、笑

終わりに

以上!ざっくりとしたstimulusの使い方でした。

htmlにdata属性を指定して、それをjsの方から扱うというのが基本です。

jQueryでは指定するclass名が必要になったりidを使用するケースが多く、マークアップのためのclassなのかjsによる指定のためのclassなのか混在しがちだと思います。

それがdata属性での指定になるので、切り分けがされるかなーと思います。

あとはそれぞれの処理ごとのテストもmodelに書いていくことでやりやすくなると思いますし、この辺はRailsに近しいので肌感としてもわかりやすいのではないかなと!

以上、stimulus触ってみたよガイドでした。