Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
stimulus
Search
Shinichi Maeshima
October 16, 2018
Technology
0
4.3k
stimulus
ginza.rb#64 でstimulusを紹介したときに使った資料です
https://ginzarb.doorkeeper.jp/events/81390
Shinichi Maeshima
October 16, 2018
Tweet
Share
More Decks by Shinichi Maeshima
See All by Shinichi Maeshima
Exceptional Rails
willnet
6
6.4k
Breaking the Flaky Test Cycle
willnet
2
1.8k
mrskで広がるインフラの選択肢
willnet
1
920
アプリケーションを長期にわたって無理なく運用するためのたったひとつの方法
willnet
2
2k
HotwireからDHHが考えるこれからのRailsとJSの付き合い方を知る
willnet
14
13k
Rails6.1で新しく入る機能について
willnet
12
15k
Concerns about Concerns
willnet
11
33k
Clean Test Code Revised
willnet
34
17k
個人でつくるwebサービス
willnet
13
9.8k
Other Decks in Technology
See All in Technology
Classmethod Odyssey 登壇資料
yamahiro
0
390
AWSサービスメニュー開発をしていてAWSを好きだ!と感じた瞬間
toru_kubota
0
130
LLMアプリケーションの評価の実践と課題 ~PharmaXにおける今後の展望~
pharma_x_tech
2
160
データ分析基盤を作ってみよう~設計編~
nrinetcom
PRO
1
110
[2024最新版]AWS Control Towerを使ったセキュアなマルチアカウント環境の作り方
hiashisan
0
270
年間一億円削減した時系列データベースのアーキテクチャ改善~不確実性の高いプロジェクトへの挑戦~
lycorptech_jp
PRO
3
2.9k
Docker互換のセキュアなコンテナ実行環境「Podman」超入門
devops_vtj
6
3.2k
簡単に始めるSnowflakeの機械学習
nayuts
1
190
目標設定は好きですか? アジャイルとともに目標と向き合い続ける方法 / Do you like target Management?
kakehashi
10
3k
データベース研修 DB基礎【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
210
エンジニア向け会社紹介資料
caddi_eng
14
220k
テスト・設計研修【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
170
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1026
450k
Robots, Beer and Maslow
schacon
PRO
157
8.1k
The Power of CSS Pseudo Elements
geoffreycrofte
64
5.2k
Happy Clients
brianwarren
94
6.5k
How to name files
jennybc
67
96k
Visualization
eitanlees
139
14k
How To Stay Up To Date on Web Technology
chriscoyier
784
250k
Designing with Data
zakiwarfel
96
5k
Building Applications with DynamoDB
mza
89
5.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Making the Leap to Tech Lead
cromwellryan
127
8.7k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
248
20k
Transcript
stimulus — ginza.rb#64 — @willnet
とは — Stimulus: A modest JavaScript framework for the HTML
you already have. — Basecamp製のJSフレームワーク — 現在のバージョン1.1.0(2018/8/23)
試用 — webpackなどでプリコンパイルするのを推奨 — cloneしてサッと試せるお試し用リポジトリがある — stimulusjs/stimulus-starter: A humble blank
slate for a modest JavaScript framework — rails使いなら rails new --webpack=stimulus yourappname でも環境作れるのでそっちでもよさそう — 公式チュートリアル的なのがあるので、それを見ながら手 を動かすとよいのでは
特徴 — react や vue.js とは志向がぜんぜん違う — データバインディングとかVirtual DOMとか、なにそれ 美味しいの?って感じ
— あくまでサーバが吐くHTMLと仲良くするためのフレーム ワーク — turbolinks friendly — サーバサイドの人が片手間でやるフロントエンドで、 vue.jsなどを導入する余裕がない…みたいなときに導入す るのが良いのでは、という気がする — 現行のjsを整理するために使う
どういうときに便利そうか — 通常RailsのJSはファイルごとにそれっぽく関数やイベント 登録などが整理されるけれど、特に強制力はない — なのでフラットにイベントが登録されたり、関数が登録 されたりする可能性がある — 例えば users.js
に user とあまり関係ない関数が 登録されたりする — DOMのclass属性とjsが紐付けられる事が多いけど、cssのた めに使うclassなのかjsで使うclassなのか分かりづらい — stimulusを使うとDOMに controller, target, action を割 り振ることができ、規約によって関数群を整理できる、と いうのがstimulusのキモの一つ(だと思う)
どういうときに便利そうか — turbolinksを使っているときに、特定のページでだけ実行 したい処理を書くのが面倒 — 特定のDOMがあるかチェックして、なかったらreturnす る、みたいな処理を毎回書く — だるい
こういうやつ $(document).on('ready turbolinks:load', () => { const target = $('.condition_transfer_on')
if (target.length === 0) { return } // .condition_transfer_on͕͋ͬͨ߹ͷॲཧ — stimulusを使うと「controllerがページ表示されたタイミ ング(connectされたタイミング)でなにか処理を実行する」 みたいなのが楽にかける
controller, target, action とは stimulus 公式のトップページを見ながら解説するとわかりや すそう Stimulus: A modest
JavaScript framework for the HTML you already have.
HTMLのコード <div data-controller="hello"> <input data-target="hello.name" type="text"> <button data-action="click->hello#greet"> Greet </button>
<span data-target="hello.output"> </span> </div>
jsのコード import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "name", "output" ] greet() { this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!` } }
結果 名前を入力してGreet!をクリックすると、右側に名前を含んだ 文字列が出力される
HTMLとjsの対応付け — data-controllerの値とjsファイル名が紐付いている — data-actionの値とメソッドが紐付いている — data-targetの値とstatic targets = []
で定義された値が 紐付いている — static targets = ["name"] などとすると、 this.nameTarget でDOMの要素を扱うことができるよう になる
stimulusの大まかな機能は これだけ
完?
それぞれもうちょっと詳し く
controller — html中のdata-controllerに合わせて、紐付いた名前の controllerをインスタンス化し、DOMと紐づけてくれる — 例えば<div data-controller="hello"> であれば hello-controller.jsが自動的に読み込まれる —
ファイル名にアンダースコアを使うこともできる — date_picker_controller.js -> date-picker — 参考: https://stimulusjs.org/handbook/ installing#controller-filenames-map-to- identifiers
複数のコントローラを一つのDOMに紐付けること ができる <div data-controller="clipboard list-item"></div>
コントローラを複数のDOMに紐付けることができ る <ul> <li data-controller="list-item">One</li> <li data-controller="list-item">Two</li> <li data-controller="list-item">Three</li> </ul>
li要素それぞれに、別々のコントローラのインスタンスが割り 当てられる
action <div data-controller="gallery"> <button data-action="click->gallery#next">…</button> </div> — イベントの名前(click) — コントローラ名(garraly)
— アクション名(next) をそれぞれ指定する
eventオブジェクト actionとして定義されたメソッドに、eventオブジェクトが引 数として渡ってくる import { Controller } from "stimulus" export
default class extends Controller { next(event) { // … } }
eventオブジェクト — event.type でなんのイベントなのかが返る(例: 'click') — event.targetでどのDOM発祥なのか返る — event.currentTargetでイベントリスナが登録されている DOMが返る
イベントの名前 — DOM要素によっては省略できる — 例えばa要素ならclickがデフォルトで省略可能
同じDOMに複数イベント登録できる <input type="text" data-action="focus->field#highlight input->search#update">
target Action以外のDOMとjsの紐づけはtargetでやる
html <div data-controller="search"> <input type="text" data-target="search.query"> <div data-target="search.errorMessage"></div> <div data-target="search.results"></div>
</div> controller໊.target໊ で指定する
js import { Controller } from "stimulus" export default class
extends Controller { static targets = [ "query", "errorMessage", "results" ] // … } — statis targets に配列でtargetになる要素の名前を渡す — すると後述のプロパティが生える
プロパティ 例えばqueryという名前のtargetを指定すると次のプロパティ が自動で生える — this.queryTarget — 最初にマッチしたDOMが返る — this.queriesTarget —
マッチしたDOMが全部返る — this.hasQueryTarget — DOMが存在しているのかbooleanで返る
一つのDOMに複数のtargetを指定できる <form data-controller="search checkbox"> <input type="checkbox" data-target="search.projects checkbox.input"> <input type="checkbox"
data-target="search.messages checkbox.input"> … </form>
Data Maps <div data-controller="content-loader" data-content-loader-url="/messages"> </div> — 状態をどこで持つのか、という話 — 他のjsフレームワークはjsで持つけど、stimulusjsはDOMで
持つ — html側からjs(その逆も)になにかデータを渡すとき、data- ίϯτϩʔϥ໊-σʔλ໊で渡すというのがstimulusjsでの お作法
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の値を取 得できる
その他のメソッド — this.data.set(key, value) — DOMの方にデータを設定する — this.data.has(key) — booleanで、そのkeyのdataが存在しているのか返す
— this.data.delete(key) — keyに紐づくdataを消す
注意点 — dataはNumberでアサインしても、getするとStringで返って くる — とくに型変換とかはしてないもよう this.data.set("count", 1) this.data.get("count") //
"1"
Lifecycle Callback controllerのインスタンスがDOMに割り当てられたときなどに hookしてメソッド実行をさせることができる import { Controller } from "stimulus"
export default class extends Controller { connect() { // … } }
メソッド — initialize — controllerのインスタンスが作られたタイミング — connect — DOMに紐付いたタイミング —
ドキュメント上にdata-controllerを持つDOMが現れたら connectされる — disconnect — DOMとの紐づけがなくなったタイミング — data-controllerを持つDOMが消されたり、data- controller属性自体が消されたりしたらdisconnect
DOMが存在する/しないで自動でcontrollerが紐付けられるというのが — turbolinksフレンドリーってことっぽい?
インスタンスは使い回される — disconnectしたあとにまたconnectされるケースでは、イン スタンスが使い回される — つまりconnectやdisconnectは複数回呼ばれる可能性が ある
まとめ
メリット — 学習コストがめっちゃ低い — 一日あれば使えるようになるのでは? — vannilajsやjQueryで作っているサービスから移行しやすい — 試してみた結果やめたくなった場合も比較的やめやすそう
デメリット — vannilajsから移行しても「単にメソッドやイベントを整理 した」以上にはならない — マジカルな何かですごいことになる、ということはない — できることが限定的 — SPAとか無理(そういうのはturbolinks使って擬似的にや
ればいいじゃん、という考え) — JSON APIを叩いて云々、とかは考えてない — クライアントサイドでDOMを組み立てる、なんて大変で しょ?全部HTMLでやればいいんだよ
以上