Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vuexに型を付けるパターンを調べた #gotandajs

Vuexに型を付けるパターンを調べた #gotandajs

mizuki_r

July 26, 2019
Tweet

More Decks by mizuki_r

Other Decks in Technology

Transcript

  1. 管理画面 with Vue • もともとPHP Yii Frameworkが内包するUIモ ジュール+ jQuery を使っていた

    • 長年の運用と範囲の拡大にインタラクションが不 足 • システムの一部でVueを導入(半年ほど前) • Form操作の複雑化に伴い、型が欲しくなる←イマココ
  2. 悩みどころ • Vueの中でのレールが無い • サードパーティを使う必要がある • Vue+Vuex+VueRouterの範囲なら公式のライブラリ使いたい • dispatch, getters,

    commitで型が落ちる • サードパーティ(ry • これまでの「Vueを使う」インタラクションから離れる必要がある • Vuexのパターンがライブラリに引っ張られる • VuexのモジュールをVueに露出させないといけない
  3. 方針 • Vue - Vuex 間で型情報を維持する • Vuexで構築するデータ構造には固く型を付 けられる •

    将来的にはAPIの構造が変わったらコンパイ ルで気付ける構造にしたい(遠い未来)
  4. vuex + vuex-class • vuexに搭載されている型 + vuex-class を使う • 標準にもっとも近い形で書ける

    • dispatchとgetterをvuex-classが隠蔽する • Store内部でのdispatch, getterの型が抜ける • Component側のインタラクションが若干変わる
  5. 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 })
  6. 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^  ^ ^
  7. 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 ^ ^
  8. vuex-smart-module • state, getter, mutation, actionを継承してクラ ス化してModuleに集約する • ComponentからはModuleを呼び出す •

    Vuexの機能単位で分割できる部分を残しているので 既存構造にも適応させやすい • Contextの概念があり、ネストしたModuleへの dispatch, getterが呼び出せる
  9. 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 ^ 
  10. Vuex-Typeパターン • Vuexに対して型を付与パターン(既存のVuexと相 性が良い) • vuex • vuex-type-helper, etc •

    モジュール化パターン(新しくモジュール構成を考 える) • vuex-module-decorator, • vuex-smart-module, etc