$30 off During Our Annual Pro Sale. View Details »

stimulus

 stimulus

ginza.rb#64 でstimulusを紹介したときに使った資料です

https://ginzarb.doorkeeper.jp/events/81390

Shinichi Maeshima

October 16, 2018
Tweet

More Decks by Shinichi Maeshima

Other Decks in Technology

Transcript

  1. stimulus
    — ginza.rb#64
    — @willnet

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. HTMLのコード



    Greet




    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  14. 完?

    View Slide

  15. それぞれもうちょっと詳し

    View Slide

  16. 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

    View Slide

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

    View Slide

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


    One
    Two
    Three

    li要素それぞれに、別々のコントローラのインスタンスが割り
    当てられる

    View Slide

  19. action



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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. html





    controller໊.target໊ で指定する

    View Slide

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

    View Slide

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

    View Slide

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





    View Slide

  29. Data Maps
    data-content-loader-url="/messages">

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

    View Slide

  30. 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の値を取
    得できる

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. まとめ

    View Slide

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

    View Slide

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

    View Slide

  40. 以上

    View Slide