Slide 1

Slide 1 text

stimulus — ginza.rb#64 — @willnet

Slide 2

Slide 2 text

とは — Stimulus: A modest JavaScript framework for the HTML you already have. — Basecamp製のJSフレームワーク — 現在のバージョン1.1.0(2018/8/23)

Slide 3

Slide 3 text

試用 — webpackなどでプリコンパイルするのを推奨 — cloneしてサッと試せるお試し用リポジトリがある — stimulusjs/stimulus-starter: A humble blank slate for a modest JavaScript framework — rails使いなら rails new --webpack=stimulus yourappname でも環境作れるのでそっちでもよさそう — 公式チュートリアル的なのがあるので、それを見ながら手 を動かすとよいのでは

Slide 4

Slide 4 text

特徴 — react や vue.js とは志向がぜんぜん違う — データバインディングとかVirtual DOMとか、なにそれ 美味しいの?って感じ — あくまでサーバが吐くHTMLと仲良くするためのフレーム ワーク — turbolinks friendly — サーバサイドの人が片手間でやるフロントエンドで、 vue.jsなどを導入する余裕がない…みたいなときに導入す るのが良いのでは、という気がする — 現行のjsを整理するために使う

Slide 5

Slide 5 text

どういうときに便利そうか — 通常RailsのJSはファイルごとにそれっぽく関数やイベント 登録などが整理されるけれど、特に強制力はない — なのでフラットにイベントが登録されたり、関数が登録 されたりする可能性がある — 例えば users.js に user とあまり関係ない関数が 登録されたりする — DOMのclass属性とjsが紐付けられる事が多いけど、cssのた めに使うclassなのかjsで使うclassなのか分かりづらい — stimulusを使うとDOMに controller, target, action を割 り振ることができ、規約によって関数群を整理できる、と いうのがstimulusのキモの一つ(だと思う)

Slide 6

Slide 6 text

どういうときに便利そうか — turbolinksを使っているときに、特定のページでだけ実行 したい処理を書くのが面倒 — 特定のDOMがあるかチェックして、なかったらreturnす る、みたいな処理を毎回書く — だるい

Slide 7

Slide 7 text

こういうやつ $(document).on('ready turbolinks:load', () => { const target = $('.condition_transfer_on') if (target.length === 0) { return } // .condition_transfer_on͕͋ͬͨ৔߹ͷॲཧ — stimulusを使うと「controllerがページ表示されたタイミ ング(connectされたタイミング)でなにか処理を実行する」 みたいなのが楽にかける

Slide 8

Slide 8 text

controller, target, action とは stimulus 公式のトップページを見ながら解説するとわかりや すそう Stimulus: A modest JavaScript framework for the HTML you already have.

Slide 9

Slide 9 text

HTMLのコード
Greet

Slide 10

Slide 10 text

jsのコード import { Controller } from "stimulus" export default class extends Controller { static targets = [ "name", "output" ] greet() { this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }

Slide 11

Slide 11 text

結果 名前を入力してGreet!をクリックすると、右側に名前を含んだ 文字列が出力される

Slide 12

Slide 12 text

HTMLとjsの対応付け — data-controllerの値とjsファイル名が紐付いている — data-actionの値とメソッドが紐付いている — data-targetの値とstatic targets = [] で定義された値が 紐付いている — static targets = ["name"] などとすると、 this.nameTarget でDOMの要素を扱うことができるよう になる

Slide 13

Slide 13 text

stimulusの大まかな機能は これだけ

Slide 14

Slide 14 text

完?

Slide 15

Slide 15 text

それぞれもうちょっと詳し く

Slide 16

Slide 16 text

controller — html中のdata-controllerに合わせて、紐付いた名前の controllerをインスタンス化し、DOMと紐づけてくれる — 例えば
であれば hello-controller.jsが自動的に読み込まれる — ファイル名にアンダースコアを使うこともできる — date_picker_controller.js -> date-picker — 参考: https://stimulusjs.org/handbook/ installing#controller-filenames-map-to- identifiers

Slide 17

Slide 17 text

複数のコントローラを一つのDOMに紐付けること ができる

Slide 18

Slide 18 text

コントローラを複数のDOMに紐付けることができ る
  • One
  • Two
  • Three
li要素それぞれに、別々のコントローラのインスタンスが割り 当てられる

Slide 19

Slide 19 text

action
— イベントの名前(click) — コントローラ名(garraly) — アクション名(next) をそれぞれ指定する

Slide 20

Slide 20 text

eventオブジェクト actionとして定義されたメソッドに、eventオブジェクトが引 数として渡ってくる import { Controller } from "stimulus" export default class extends Controller { next(event) { // … } }

Slide 21

Slide 21 text

eventオブジェクト — event.type でなんのイベントなのかが返る(例: 'click') — event.targetでどのDOM発祥なのか返る — event.currentTargetでイベントリスナが登録されている DOMが返る

Slide 22

Slide 22 text

イベントの名前 — DOM要素によっては省略できる — 例えばa要素ならclickがデフォルトで省略可能

Slide 23

Slide 23 text

同じDOMに複数イベント登録できる

Slide 24

Slide 24 text

target Action以外のDOMとjsの紐づけはtargetでやる

Slide 25

Slide 25 text

html
controller໊.target໊ で指定する

Slide 26

Slide 26 text

js import { Controller } from "stimulus" export default class extends Controller { static targets = [ "query", "errorMessage", "results" ] // … } — statis targets に配列でtargetになる要素の名前を渡す — すると後述のプロパティが生える

Slide 27

Slide 27 text

プロパティ 例えばqueryという名前のtargetを指定すると次のプロパティ が自動で生える — this.queryTarget — 最初にマッチしたDOMが返る — this.queriesTarget — マッチしたDOMが全部返る — this.hasQueryTarget — DOMが存在しているのかbooleanで返る

Slide 28

Slide 28 text

一つのDOMに複数のtargetを指定できる …

Slide 29

Slide 29 text

Data Maps
— 状態をどこで持つのか、という話 — 他のjsフレームワークはjsで持つけど、stimulusjsはDOMで 持つ — html側からjs(その逆も)になにかデータを渡すとき、data- ίϯτϩʔϥ໊-σʔλ໊で渡すというのがstimulusjsでの お作法

Slide 30

Slide 30 text

js // controllers/content_loader_controller.js import { Controller } from "stimulus" export default class extends Controller { connect() { fetch(this.data.get("url")).then(/* … */) } } — this.data.get("url")でdata-content-loader-urlの値を取 得できる

Slide 31

Slide 31 text

その他のメソッド — this.data.set(key, value) — DOMの方にデータを設定する — this.data.has(key) — booleanで、そのkeyのdataが存在しているのか返す — this.data.delete(key) — keyに紐づくdataを消す

Slide 32

Slide 32 text

注意点 — dataはNumberでアサインしても、getするとStringで返って くる — とくに型変換とかはしてないもよう this.data.set("count", 1) this.data.get("count") // "1"

Slide 33

Slide 33 text

Lifecycle Callback controllerのインスタンスがDOMに割り当てられたときなどに hookしてメソッド実行をさせることができる import { Controller } from "stimulus" export default class extends Controller { connect() { // … } }

Slide 34

Slide 34 text

メソッド — initialize — controllerのインスタンスが作られたタイミング — connect — DOMに紐付いたタイミング — ドキュメント上にdata-controllerを持つDOMが現れたら connectされる — disconnect — DOMとの紐づけがなくなったタイミング — data-controllerを持つDOMが消されたり、data- controller属性自体が消されたりしたらdisconnect

Slide 35

Slide 35 text

DOMが存在する/しないで自動でcontrollerが紐付けられるというのが — turbolinksフレンドリーってことっぽい?

Slide 36

Slide 36 text

インスタンスは使い回される — disconnectしたあとにまたconnectされるケースでは、イン スタンスが使い回される — つまりconnectやdisconnectは複数回呼ばれる可能性が ある

Slide 37

Slide 37 text

まとめ

Slide 38

Slide 38 text

メリット — 学習コストがめっちゃ低い — 一日あれば使えるようになるのでは? — vannilajsやjQueryで作っているサービスから移行しやすい — 試してみた結果やめたくなった場合も比較的やめやすそう

Slide 39

Slide 39 text

デメリット — vannilajsから移行しても「単にメソッドやイベントを整理 した」以上にはならない — マジカルな何かですごいことになる、ということはない — できることが限定的 — SPAとか無理(そういうのはturbolinks使って擬似的にや ればいいじゃん、という考え) — JSON APIを叩いて云々、とかは考えてない — クライアントサイドでDOMを組み立てる、なんて大変で しょ?全部HTMLでやればいいんだよ

Slide 40

Slide 40 text

以上