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

破綻しない Vue.js アプリケーション開発のために大切なこと / How to make a robust Vue.js application

破綻しない Vue.js アプリケーション開発のために大切なこと / How to make a robust Vue.js application

2018/10/15 に JSLounge の活動として UUUM株式会社様で行った発表のスライドです。

potato4d(Hanatani Takuma)

October 15, 2018
Tweet

More Decks by potato4d(Hanatani Takuma)

Other Decks in Programming

Transcript

  1. Profile • Ֆ୩ ୓ຏ as known as potato4d • Vue.js

    / Nuxt.js Japanese Document • Translator / maintainer • Vue.js Japan user group • Staff / Vue Fes Japan 2018 staff • Nuxt.js beginners guide author
  2. ٕज़τϨϯυʹ߹Θͤͨมભ • Vue.js 1.0 ͸ 3 ೥લɺ Vue.js 2.0 ͸

    2 ೥લɺ࣍ͷ v3 ͸…… • ʮݹ͘ͳΔͱ৘ใ΋૿͑ͣศརͳ΋ͷ΋࢖͑ͳ͍ʯ • ʮՄೳͰ͋Ε͹࣌ؒΛͱͬͯ΋࠷௿ݶϝδϟʔ͸͍͋͛ͨʯ
  3. ࠷ऴతʹ࢒Δͷ͸……ʁ ✘ Vue.js ΍ UI ʹܹ͘͠ґଘͨ͠෦෼ ✘ Build environment ✘

    ྲྀߦΓͷϥΠϒϥϦʹΑ࣮ͬͯ૷͞Εͨ෦෼ ✘ υϝΠϯશҬ(ഽײίʔυϕʔεͷ6ׂఔ౓͸Ҡ২Մೳ) ˕ ϓϩδΣΫτʹ͋Θ͍ͤͨΘΏΔʮϢʔςΟϦςΟʯ ˕ ൚༻తͳ(Ξφ΢ϯε΍௨஌ͳͲͷ)ίϯϙʔωϯτͷϩδοΫ
  4. Vue.js / SFC ʹͩ͜ΘΓ͗͢ͳ͍ • Vue.js ͔ͩΒͱ͍ͬͯશͯΛ .vue Ͱ׬݁ͤ͞Δඞཁ͸ͳ͍ •

    SFC ͸ Vue Test Utils Λར༻ͨ͠είʔϓͷେ͖͍ςετͳͲ ͕ඞཁʹͳΔͷͰඞવੑͷ͋Δ੹຿͚ͩΛ΋ͨͤΔ • ͋ͱ͸ VanillaJS ʹΑΔهड़Λ৺͕͚Δ • ৄ͘͠͸࣍ͷηΫγϣϯͰ
  5. ͜Μͳίϯϙʔωϯτ࡞ͬͯ·ͤΜ͔ʁ <template> <button @click=“like”>Like</button> </template> <script> import { mapActions }

    from ‘vuex’ export default { props: { id: Number }, methods: { click() { this.like({ id }) }, .. .mapActions(‘entries’, [‘like’])
 }
 } </script> -JLF#VUUPOWVF
  6. ͜Μͳίϯϙʔωϯτ࡞ͬͯ·ͤΜ͔ʁ <template> <button @click=“like”>Like</button> </template> <script> import { mapActions }

    from ‘vuex’ export default { props: { id: Number }, methods: { click() { this.like({ id }) }, .. .mapActions(‘entries’, [‘like’])
 }
 } </script> Atoms ૬౰ͷϞϊ͕ Vuex ʹґଘ͍ͯ͠Δ -JLF#VUUPOWVF
  7. վળྫ <template> <button @click="like">Like</button> </template> <script> export default { methods:

    { click(event) { this.$emit('click', event) } }
 } </script> Vue.js ͷΠϕϯτγεςϜΛ࢖ͬͯ੹຿Λബ͘ -JLF#VUUPOWVF
  8. ͜Μͳίϯϙʔωϯτ࡞ͬͯ·ͤΜ͔ʁ <template> <div class=“some-form”> <template v-if=“mode === ‘new’”> <div></div> </template>

    <template v-if=“mode === ‘edit’”> <div></div> </template> <!-— code --> </div> </template> <script> export default { props: { mode: String } } </script> 6TFS'PSNWVF
  9. ͜Μͳίϯϙʔωϯτ࡞ͬͯ·ͤΜ͔ʁ <template> <div class=“some-form”> <template v-if=“mode === ‘new’”> <div></div> </template>

    <template v-if=“mode === ‘edit’”> <div></div> </template> <!-— code --> </div> </template> <script> export default { props: { mode: String } } </script> ίϯϙʔωϯτʹೋͭҎ্ͷ໾ׂ͕͋Δ 6TFS'PSNWVF
  10. վળྫ <template> <div class=“some-form”> <template> <div> <!-— code --> </div>

    </template> </div> </template> <script> export default { } </script> 6TFS$SFBUF'PSNWVF ৑௕ʹͳͬͯ΋ͦΕͧΕผͷίʔυʹ͢Δ
  11. վળྫ <template> <div class=“some-form”> <template> <div> <!-— code --> </div>

    </template> </div> </template> <script> export default { } </script> 6TFS&EJU'PSNWVF ผͷίʔυʹ͓ͯ͘͠ͱʮߋ৽ෆՄʯͷ߲໨ͷ࣮૷΋༰қ
  12. ͜ΜͳίʔυΛॻ͍ͯ·ͤΜ͔ʁ import { mapGetters, mapActions } from 'vuex' export default

    { computed: { ...mapGetters('entries', { form: 'editEntry' })
 }, methods: { ...mapActions('entries', ['updateEditEntry', 'updateEntry']) } } &OUSZ&EJU'PSNWVF
  13. ͜ΜͳίʔυΛॻ͍ͯ·ͤΜ͔ʁ import { mapGetters, mapActions } from 'vuex' export default

    { computed: { ...mapGetters('entries', { form: 'editEntry' })
 }, methods: { ...mapActions('entries', ['updateEditEntry', 'updateEntry']) } } &OUSZ&EJU'PSNWVF 1. ίϯϙʔωϯτ͚͕ͩ஌͍ͬͯΕ͹ྑ͍தؒঢ়ଶʹVuexΛ࢖͍ͬͯΔ 2. Vuex ͷ mapXXX ͷΤΠϦΞεػೳͷ͍ͤͰ grep ͮ͠Β͘ͳ͍ͬͯΔ
  14. ͜ΜͳίʔυΛॻ͍ͯ·ͤΜ͔ʁ /* ... state code ... */ const getters =

    { entries: [], editEntry: null } /* ... mutation code ... */ const actions = { // ... other actions updateEditEntry({ commit }, { formData }) {commit('updateEditEntry', formData)} } export default { namespaced: true, state, mutations, getters, actions } FOUSJFTKT υϝΠϯ֓೦͕ೖ͍ͬͯΔ͸ͣͷ entries ʹԿނ͔ϑΥʔϜͷঢ়ଶ͕
  15. मਖ਼ྫ import { mapGetters, mapActions } from 'vuex' export default

    { data() { const form = this.entries.find((e) => e.id == this.$route.params.id)) return { form
 } }, computed: { ...mapGetters('entries', ['entries'])
 }, methods: { ...mapActions('entries', ['updateEntry']) } } &OUSZ&EJU'PSNWVF 1. தؒঢ়ଶ͸ϩʔΧϧεςʔτʹด͡ࠐΊͯ Vuex ʹΰϛσʔλ͕࢒Βͳ͍Α͏ʹ 2. ೖྗ͕Ωϟϯηϧ͞Εͨ৔߹΋ίϯϙʔωϯτͷϥΠϑαΠΫϧʹΑͬͯద੾ʹഁغ
  16. मਖ਼ྫ /* ... state code ... */ const getters =

    { entries: [] } /* ... mutation code ... */ const actions = { updateEntry() {} // ࣮ࡍͷσʔλͷߋ৽͚ͩΛߦ͏ } export default { namespaced: true, state, mutations, getters, actions } FOUSJFTKT Vuex ͸࣮σʔλʹͷΈઐ೦Ͱ͖ɺ͔ͭԼखʹϦηοτॲཧΛॻ͔ͳ͍Ͱྑ͍Α͏ʹ
  17. ͜ΜͳίʔυΛॻ͍ͯ·ͤΜ͔ʁ <script> export default { data() { return { formData:

    { val1: '', val2: '' }, status: '' } // ద౰ͳঢ়ଶ
 } methods: { handleAction() {
 const foo = this.covert({…this.formData}) this.$store.dispatch('namespace/someAction', foo)
 }, convert(args) { return {...args} // Կ͔͠ΒͷॲཧΛߦͬͨޙʹฦ٫ } } } .Z$PNQPOFOUWVF
  18. ͜ΜͳίʔυΛॻ͍ͯ·ͤΜ͔ʁ <script> export default { data() { return { formData:

    { val1: '', val2: '' }, status: '' } // ద౰ͳঢ়ଶ
 } methods: { handleAction() {
 const foo = this.covert({…this.formData}) this.$store.dispatch('namespace/someAction', foo)
 }, convert(args) { return {...args} // Կ͔͠ΒͷॲཧΛߦͬͨޙʹฦ٫ } } } ୯ҰϑΝΠϧίϯϙʔωϯτͰ΋ͭඞཁͷͳ͍ॲཧ͕ଘࡏ͢Δ (ಛʹෳ਺ͷίϯϙʔωϯτͰग़ݱ͢Δ৔߹) .Z$PNQPOFOUWVF
  19. मਖ਼ྫ function convert(args) { return {...args}
 } export default convert

    VUJMTDPOWFSUFSKT JavaScript ͚ͩͰ׬݁͢Δ෦෼͸ JavaScriptͰ੾Γग़͢
  20. मਖ਼ྫ import convert from './converter' describe('converter.js', () => { test('test

    code', () => { const input = { val1: '', val2: '' } expect(convert(input)).toMatchObject(input) }) }) TQFDVUJMTDPOWFSUFSTQFDKT JavaScript Ͱॻ͘͜ͱͰςετίʔυ΋هड़͠΍͘͢
  21. Vue CLI v3 • Vue.js ۘ੡ͷ CLI πʔϧ • طଘͷ؀ڥ(ࣗྗͰ

    webpack Λ৮Δ؀ڥ)͔Β΋Ҡߦ͠΍͍͢ • CLIπʔϧͷԆ௕Β͍͠ػೳ͕๛෋ • ϓϥάΠϯʹΑΔ؀ڥͷڧԽ͕༰қ • ϓϥάΠϯʹΑΔ؀ڥͷߏங͕༰қ • ίϚϯυҰൃͰςετ؀ڥͳͲΛ࡞੒Մೳ • ։ൃମݧͱͯ͠͸؀ڥ΍଍ճΓΛڧԽ͢Δཁૉ͕ڧ͍
  22. 7VF$-*W1SPKFDU 7VF$-*4FSWJDF 5FTUJOH Vue CLI v3 ༗ޮ׆༻͢Δ 7VFKT 7VF3PVUFS 7VFY

    7VF5FTU6UJMT 1VSF+BWB4DSJQU &YUFSOBM4FSWJDF )551 6UJMJUZ
  23. Nuxt.js • Vue.js ͔ΒݟΔ৔߹͸ඇެࣜͷϑϨʔϜϫʔΫ • Vue.js ͷίϛϡχςΟύʔτφʔͱͳͬͨͷͰڠྗؔ܎Ͱ͸͋Δ • ϑϨʔϜϫʔΫΒ͍͠ػೳΛఏڙ͢Δ •

    ಠࣗͷϞδϡʔϧ΍ϓϥάΠϯγεςϜ • ΦʔτϩʔσΟϯάܥͷػೳ΍ SSR ͷσϑΥϧταϙʔτ • ϓϩδΣΫτͷجຊઃܭΛ Nuxt.js ʹ೚ͤΔ͜ͱ͕Ͱ͖Δ • ։ൃମݧͱͯ͠͸ϓϩδΣΫτઃܭΛڧԽ͢Δཁૉ͕ڧ͍
  24. Vue CLI v3 or Nuxt.js • ར༻Ϟνϕʔγϣϯ͔Βͯ͠ҧ͏ͷͰҰ֓ʹ͸ൺֱతͰ͖ͳ͍ • ݸਓతʹ͸ Vue.js

    ͷϏΪφʔ͕গͳ͍৔߹͸ Nuxt.js Λਪ঑ • ͍͖ͳΓ Nuxt.js Λ৮Δͷ͸ϋʔυϧ͕ߴ͍ͷͰඇਪ঑ • ͋Δఔ౓׳Εͨਓ͕ Nuxt.js ͰҰ௨Γ૊ΜͰ͠·͑͹ϏΪφʔ͕͋ ͱ͔Βೖͬͯ΋յΕͳ͍Α͏ͳઃܭ͕Ͱ͖Δ • ͲͷΈͪ 2 ೥ఔ౓ͷεύϯͰߟ͑ΔͳΒϨʔϧʹ৐ͬͯߴ͍ੜ࢈ ੑΛಘͨ΄͏͕ϓϩδΣΫτΛυϥΠϒͰ͖Δ