Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Vuexに型を付けるパターンを調べた #gotandajs
Search
mizuki_r
July 26, 2019
Technology
160
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Vuexに型を付けるパターンを調べた #gotandajs
mizuki_r
July 26, 2019
More Decks by mizuki_r
See All by mizuki_r
FrontendUp_新規事業で_Remixを採用した理由と対策.pdf
rymizuki
0
270
税理士ドットコムの 技術的挑戦 #tapioca_lt
rymizuki
0
330
PHPを始めて1年、レガシーシステムにどう向き合っているか #phpstudy
rymizuki
1
870
モダンとレガシー #gotandaem
rymizuki
0
610
DockerでNodeの開発は厳しいのか? #gotandajs
rymizuki
3
440
マネージャー!きみは何者だ! #gotandaem
rymizuki
0
1.9k
物語を楽しむための物語論
rymizuki
0
580
失敗と向き合う
rymizuki
0
1.6k
社内勉強会と組織の成長を考える
rymizuki
1
2.8k
Other Decks in Technology
See All in Technology
The future of architectural work
ufried
0
170
cdkd (CDK Direct)
gotok365
3
250
[General] 개발자로 해외 기업에서 일하기
skydoves
1
300
サボる子はいねぇがー!AgentCoreハーネスの脆弱性に学ぶ、エージェントの入力バリデーション
iwamot
PRO
4
280
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
200
今から始めるAWS環境の暗号移行 - ポスト量子時代に備える
sato4mi
0
150
bpf_arenaとstruct_opsを使うのが難しかった話
masu_mi
0
200
超⼩型・多⾔語検索モデル Bekko Embedding
hotchpotch
1
110
TSKaigi Sendai 2026 - tsgo時代のTypeScript Playgroundはどう動くか
teamlab
PRO
0
110
Building Audio Plugin Ecosystem for Android in 2026
atsushieno
2
150
あなたのDartコードは丸見えかもしれない ~reFlutterで暴くFlutterアプリの中身と多層防御~
zozotech
PRO
0
770
Oracle Database Security 詳細解説
oracle4engineer
PRO
2
270
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
187
23k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
350
Designing Experiences People Love
moore
143
24k
Music & Morning Musume
bryan
48
7.5k
Mobile First: as difficult as doing things right
swwweet
225
10k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.7k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Optimizing for Happiness
mojombo
378
71k
Unsuck your backbone
ammeep
672
58k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
970
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
320
A Soul's Torment
seathinner
8
3.9k
Transcript
Vuexに型を付けるパターン を調べた 2019/07/26 Gotanda.js #12 @mizuki_r
@mizuki_r 弁護士ドットコム株式会社 税理士ドットコム事業部/開発チーム チームマネージャー 2 自己紹介 PHP, Vue, Nuxt, Management,
Recruitment, etc…
今日のお話
運用中のサービスに Vue+TypeScriptを導入した話
ーーを、しようと思ったが…
Vuexの型付けで悩み…
今日までに 結論が出せなかった…
ーーので、 Vuexの型付を調べた話 をします
免責事項 • 個人の見解に基づく発表であり組織・団体の主張する意見 ではありません • 業務の片手間でググった範囲なので最新の情報ではない可 能性があります • 時間の都合上、各ライブラリの型定義までしっかり読み込 んできたわけではないので間違いがあるかもしれません
• 予めご了承ください
背景
税理士ドットコム • 日本最大級の税理士/税務ポータルサイト • 税理士紹介、Q&A、ニュースなど • 2016年〜 • 私 +
業務委託エンジニアx5
管理画面 with Vue • もともとPHP Yii Frameworkが内包するUIモ ジュール+ jQuery を使っていた
• 長年の運用と範囲の拡大にインタラクションが不 足 • システムの一部でVueを導入(半年ほど前) • Form操作の複雑化に伴い、型が欲しくなる←イマココ
型に対する期待 • データ構造の補完 • データ構造のドキュメント化 • 値の受け渡しミスの抑止 • メンバーの学習
悩みどころ • Vueの中でのレールが無い • サードパーティを使う必要がある • Vue+Vuex+VueRouterの範囲なら公式のライブラリ使いたい • dispatch, getters,
commitで型が落ちる • サードパーティ(ry • これまでの「Vueを使う」インタラクションから離れる必要がある • Vuexのパターンがライブラリに引っ張られる • VuexのモジュールをVueに露出させないといけない
方針
前提 • Vueを使う • メンバーの知識的、学習補助のコスパ的に • 段階的にTypeScriptを導入する • 全体をまとめて、はリスクとコスト的にやらない •
Multiple Page Application + Single Page Application • システムの一部をSPAにする
方針 • Vue - Vuex 間で型情報を維持する • Vuexで構築するデータ構造には固く型を付 けられる •
将来的にはAPIの構造が変わったらコンパイ ルで気付ける構造にしたい(遠い未来)
Vuex + TypeScriptの パターンを調べた
パターン • vuex + vuex-class • vuex-type-helper + vuex-class •
vuex-module-decorator • vuex-smart-module
vuex + vuex-class
vuex + vuex-class • vuexに搭載されている型 + vuex-class を使う • 標準にもっとも近い形で書ける
• dispatchとgetterをvuex-classが隠蔽する • Store内部でのdispatch, getterの型が抜ける • Component側のインタラクションが若干変わる
import Vue from 'vue' import Vuex, { GetterTree, MutationTree, ActionTree
} from 'vuex' import { RootState, NoteForm } from './types' import * as notes from './notes' Vue.use(Vuex) const state: RootState = {} const getters: GetterTree<RootState, RootState> = { getNotes(state) { return () => (state.notes ? state.notes.rows : []) } } const mutations: MutationTree<RootState> = {} const actions: ActionTree<RootState, RootState> = { async viewIndex(ctx) { ctx.dispatch('notes/fetch') }, async addNote(ctx, form: NoteForm) { ctx.dispatch('notes/add', form) } } const modules = { notes } export default new Vuex.Store({ state, mutations, actions, modules })
vuex-type-helper
vuex-type-helper • vuexの型ではなくvuex-type-helperを使う • interfaceに基づいて片付けができる • dispatchとgetterにinterfaceを適応できる • ネストモジュールに対してはすべてのaction とpayloadをinterfaceに記載する必要がある
JNQPSU\%FGJOF(FUUFST %FGJOF.VUBUJPOT %FGJOF"DUJPOT^GSPNWVFYUZQFIFMQFS FYQPSUDPOTUOBNFTQBDFEUSVF FYQPSUDPOTUTUBUF/PUFT4UBUF\SPXT<>^ FYQPSUDPOTUHFUUFST%FGJOF(FUUFST/PUFT(FUUFST /PUFT4UBUF 3PPU4UBUF\ SPXT TUBUF
\ SFUVSO TUBUFSPXT ^ ^ FYQPSUDPOTUNVUBUJPOT%FGJOF.VUBUJPOT/PUFT.VUBUJPOT /PUFT4UBUF\ '&5$)@3&40-7& TUBUF \SPXT^ \ TUBUFSPXTSPXT ^ "%%@3&40-7& TUBUF \GPSN^ \ DPOTUMBTU*ETUBUFSPXT<TUBUFSPXTMFOHUI>JE DPOTUOPUF/PUF&OUJUZ\ JEMBTU*E DPOUFOUGPSNDPOUFOU DSFBUFEOFX%BUF ^ TUBUFSPXTQVTI OPUF ^ ^ FYQPSUDPOTUBDUJPOT%FGJOF"DUJPOT /PUFT"DUJPOT /PUFT4UBUF /PUFT.VUBUJPOT 3PPU4UBUF \ BTZODGFUDI DUY \ DPOTUSPXT/PUF&OUJUZ<>< \JE DPOUFOUUFTU DSFBUFEOFX%BUF ^ > DUYDPNNJU '&5$)@3&40-7& \SPXT^ ^ BTZODBEE DUY \GPSN^ \ DUYDPNNJU "%%@3&40-7& \GPSN^ ^ ^
vuex-module-decorator
vuex-module-decorator • Vuexのモジュール一つのクラスとしてみなす • VuexModuleクラスを継承してデコレータで mutation, actionを定義する • vue-property-decratorに感触的には近い •
Componentからはモジュールを直接呼び出す ことで型抜けを防ぐ
JNQPSU\/PUF&OUJUZ /PUF'PSN^GSPNUZQFT JNQPSU\7VFY.PEVMF .VUBUJPO "DUJPO^GSPNWVFYNPEVMFEFDPSBUPST FYQPSUEFGBVMUDMBTT/PUFT.PEVMFFYUFOET7VFY.PEVMF\ SPXT/PUF&OUJUZ<><> !.VUBUJPO '&5$)@3&40-7& SPXT/PUF&OUJUZ<>
\ UIJTSPXTSPXT ^ !.VUBUJPO "%%@3&40-7& GPSN/PUF'PSN \ DPOTUMBTU*EUIJTSPXT<UIJTSPXTMFOHUI>JE DPOTUOPUF/PUF&OUJUZ\ JEMBTU*E DPOUFOUGPSNDPOUFOU DSFBUFEOFX%BUF ^ UIJTSPXTQVTI OPUF ^ !"DUJPO BTZODGFUDI \ DPOTUSPXT/PUF&OUJUZ<>< \JE DPOUFOUUFTU DSFBUFEOFX%BUF ^ > SFUVSOSPXT ^ !"DUJPO BTZODBEE GPSN/PUF'PSN \ SFUVSOGPSN ^ ^
vuex-smart-module
vuex-smart-module • state, getter, mutation, actionを継承してクラ ス化してModuleに集約する • ComponentからはModuleを呼び出す •
Vuexの機能単位で分割できる部分を残しているので 既存構造にも適応させやすい • Contextの概念があり、ネストしたModuleへの dispatch, getterが呼び出せる
JNQPSU\(FUUFST .VUBUJPOT "DUJPOT .PEVMF^GSPNWVFYTNBSUNPEVMF JNQPSU\/PUF&OUJUZ /PUF'PSN^GSPNUZQFT FYQPSUDPOTUOBNFTQBDFEUSVF FYQPSUDMBTT/PUFT4UBUF\ SPXT/PUF&OUJUZ<><> ^
FYQPSUDMBTT/PUFT(FUUFSTFYUFOET(FUUFST/PUFT4UBUF\ SPXT \ SFUVSOUIJTTUBUFSPXT ^ ^ FYQPSUDMBTT/PUFT.VUBUJPOTFYUFOET.VUBUJPOT/PUFT4UBUF\ '&5$)@3&40-7& SPXT/PUF&OUJUZ<> \ UIJTTUBUFSPXTSPXT ^ "%%@3&40-7& GPSN/PUF'PSN \ DPOTUMBTU*EUIJTTUBUFSPXT<UIJTTUBUFSPXTMFOHUI>JE DPOTUOPUF/PUF&OUJUZ\ JEMBTU*E DPOUFOUGPSNDPOUFOU DSFBUFEOFX%BUF ^ UIJTTUBUFSPXTQVTI OPUF ^ ^ FYQPSUDMBTT/PUFT"DUJPOTFYUFOET"DUJPOT /PUFT4UBUF /PUFT(FUUFST /PUFT.VUBUJPOT /PUFT"DUJPOT \ BTZODGFUDI \ DPOTUSPXT/PUF&OUJUZ<>< \JE DPOUFOUUFTU DSFBUFEOFX%BUF ^ > UIJTDPNNJU '&5$)@3&40-7& SPXT ^ BTZODBEE GPSN/PUF'PSN \ UIJTDPNNJU "%%@3&40-7& GPSN ^ ^ FYQPSUEFGBVMUOFX.PEVMF \ TUBUF/PUFT4UBUF HFUUFST/PUFT(FUUFST NVUBUJPOT/PUFT.VUBUJPOT BDUJPOT/PUFT"DUJPOT ^
まとめ
Vuexに型をつけようと思ったら Vuex-Frameworkの選定になった
Vuex-Typeパターン • Vuexに対して型を付与パターン(既存のVuexと相 性が良い) • vuex • vuex-type-helper, etc •
モジュール化パターン(新しくモジュール構成を考 える) • vuex-module-decorator, • vuex-smart-module, etc
何を採用するか? • Vue-Vuexの間でどういうやり取りするかが 大きく関わるので全体を考える必要がある • アプリがライブラリに依存する • サードパーティなので、アップデートの追 従とかも考えたほうがいい •
Vue+TypeScriptは発展途上
まとめ • Vuexで片付けするパターンを紹介しました • まだVuexの型は方言が多い • 「ゆるく書ける」Vueの良さとどう同居していくか模 索している • みなさんの意見を聞かせてください
ご清聴ありがとうございました