2018.06.26 に #ichigayageek で話したスライドです。 https://ichigayageek.connpass.com/event/87792/
Vue.jsϓϩδΣΫτͷരൃ͔ͤͨ͞2018.06.26 Ϛδკ #ichigayageek HANATANI Takuma(@potato4d)https://unsplash.com/photos/hLUTRzcVkqg
View Slide
ࣗݾհHANATANI Takuma(@potato4d)• ϑϦʔϥϯεͷWebΤϯδχΞ• FrontEnd / Node.js / PHP/ AWS / etc…• Vue.jsຊޠެࣜυΩϡϝϯτϝϯςφ• Vue.js Japan User Group ελοϑ• nuxt/docs ӳ/υΩϡϝϯτߩݙ• Nuxt tech book Author
JS History• Vue.js 2015 ~• Rails & Vue, SPA, SPA + SSR, Nuxt.js, with TypeScript• React 2016 ~• SPA, PHP & React, Rails & React, with TypeScript, with Flow• Angular 2017 ~• SPA, ΄΅৮ͬͯͳ͍
Vue:React:Angular=14:4:1 ͳײ͡
https://potato4d.booth.pm/items/824745
ࠓ͢͜ͱ
Vue.jsϓϩδΣΫτͷരഁํ๏
Why?
Vue.jsΛ๙ΊΔใ͍͘ΒͰ͋ΔͷͰ……
https://ichigayageek.connpass.com/event/87792/
໌ʹཱͨͳ͍͚Ͳ͍͔ͭʹཱͭ
վΊͯࠓ͢͜ͱ• ʮVue.js୭Ͱ؆୯ʹ࡞ΕΔ͚Ͳখن͚ʯຊ͔• աڈͷϓϩδΣΫτͷল͔ΒΈΔ Vue.js ͷఆઆͷධՁ• Vuex ͕͋ͬͯͳͯ͘ྑ͍ຊ͔ʁ• σβΠφʔͰ৮ΕͯҰॹʹࣄͰ͖Δຊ͔ʁ• όοΫΤϯυத৺ͷWebΞϓϦέʔγϣϯͷͪΐ͍ೖΕʹڧ͍ຊ͔ʁ• Vue.js Λ৽نͰ͏߹ʹબ͖͢͜ͱ
ఆλʔήοτ(1)• Ϟμϯ JavaScript ͱઃܭʹ͍ͭͯ࠷ݶ͍ͬͯΔਓ• ʮReact, Vue, Angular ͕ͬͯͭਓؾͳΜͰ͠ΐʯ• ʮVue.js؆୯ʹ͔͚ͯϋʔυϧ͕͍ॳ৺ऀ͚ͷͭͰ͠ΐʯ• ʮ FluxύλʔϯͬͯγϯάϧτϯͰҰํͳͭͰ͠ΐʯΈ͍ͨͳࡶͳೝࣝఔͰͷΘ͔ΔͷͰOK
ఆλʔήοτ(2)• Vue.js ͰͭΒ͍ࢥ͍Λͦ͠͏ͳਓɾͨ͠ਓ• ঢ়ଶཧͰΜͰ͍Δਓ• ϓϩδΣΫτͷنײɾνʔϜײͰͲ͏ͨ͠Βྑ͍͔Θ͔Βͳ͍ਓ͜Ε͔Βͷ։ൃΛॿ͚ʹͳΕΔͣ
ࠓ͢͜ͱ• ʮVue.js୭Ͱ؆୯ʹ࡞ΕΔ͚Ͳখن͚ʯຊ͔• աڈͷϓϩδΣΫτͷল͔ΒΈΔ Vue.js ͷఆઆͷධՁ• Vuex ͕͋ͬͯͳͯ͘ྑ͍ຊ͔ʁ• σβΠφʔͰ৮ΕͯҰॹʹࣄͰ͖Δຊ͔ʁ• όοΫΤϯυத৺ͷWebΞϓϦέʔγϣϯͷͪΐ͍ೖΕʹڧ͍ຊ͔ʁ• Vue.js Λ৽نͰ͏߹ʹબ͖͢͜ͱ
ʮ݁ہVue.jsͬͯখن͚ͳΜͰ͠ΐʯ
A. ͦ͏Ͱͳ͍
A. ͦ͏Ͱͳ͍͕ʮͪΌΜͱ։ൃʯ͢Δͷʹίπ͕ඞཁ
Vue.js PHP ͱΑ͘ࣅ͍ͯΔ
͋͑ͯ໌ݴ͢Δ ಛ
Vue.js is• ʮࡶʹ͏ͱ͢Δͱͱ͜ͱΜࡶʹΉ͜ͱ͕շదʹͰ͖Δʯ• ʮࡶʹΉͱ؆୯ʹϓϩδΣΫτΛരൃͤ͞Δʯ͜ͱ͕Ͱ͖Δ• ʮരൃ͠ͳ͍ϓϩδΣΫτΛ࡞Ζ͏ͱ͢Δͱۃʹ͘͠ͳΔʯ• ʮ༉அ͢Δͱരൃ͢Δ͚Ͳ PHP ΄Ͳരൃͯ͠ࠔͬͨΛ͕ͨ͠Βͳ͍ʯ
ࠔͬͨ with ఆઆ
աڈͷϓϩδΣΫτͷരൃ͔ΒΈΔVue.js ͷఆઆͷධՁ
ר͖Ͱ 3 ͭհ
1 / 3
ʮVuex ͋ͬͯͳͯ͘ྑ͍આʯ
A. 80%͙Β͍ͷ֬ͰӕʹͳΔ
VuexΘͣരൃͨ͠
Vuex ΛΘͳ͍Ͱരൃͨ͠(1)• 2016͙Β͍ͷ։ൃͷ• Vuex Λ Flux తʹ Single source of truth ʹ͢Δ࣌ͷ΄͏͕ଟ͔ͬͨࠒͷ• Single source of truth Λ९क͢ΔͷΓ͗ͩ͢ͱࢥ͍ Pure JavaScript Object ͰͷStore Λ࡞• σʔλͱͯ֬͠ఆͨ͠ใͷΈΛ֨ೲɻҰ࣌εςʔτVueίϯϙʔωϯτʹ࣋ͨͤͨ• require/import ࢀর͠ʹʹͳΔͷͰॻ͖͑Δͱ͏·͍۩߹ʹํόΠϯσΟϯάͱטΈ߹ͬͯ͘ΕΔ
Vuex ΛΘͳ͍Ͱരൃͨ͠(2)• ॳظ։ൃ JS Object Β͍͠औΓճ͠ͱޮͷྑ͕͞͏·͘ޮ͍͍ͯͨ• ํόΠϯσΟϯάͷԸܙ͋ͬͯɺ Reactivity Λશ໘ʹ׆༻ͨ͠ίʔυ͕ॻ͚͍ͯͨ
Vuex ΛΘͳ͍Ͱരൃͨ͠(3)• ༷͕มΘͬͨΓɺಛఆͷ API ϦιʔεͷۃͳංେԽʹΑͬͯ Pure JSΦϒδΣΫτ͔ΒಡΈऔΕͳ͍͜ͱ͕ଟ͘ͳͬͯ͘Δ• ΘΕ͍ͯͳ͍֬ূΛಘΔ͜ͱ͕͘͠ɺஈʑͱ։ൃ͕ͭΒ͘……• େ͖͘ͳΔΞϓϦέʔγϣϯ Vuex ΛೖΕ͓͖ͯͩͬͨ͘
രൃͤ͞ͳ͍ͨΊʹ
ʮVuex ΛΘͳ͍ͰരൃʯΛ͙(1)• SPA Ͱ Vuex ͳͯ͘ JS Object ετΞύλʔϯͰ͍͚Δେମӕ• ͱΓ͋͑ͣ Vuex ඞͣೖΕ͓͍ͯͯɺεςʔτͷར༻Λߟ͑Δ• Vuex ެࣜʹSingle source of truthʹ߆Δඞཁͳ͍ͱ໌ݴ͍ͯ͠ΔͷͰɺϩʔΧϧεςʔτͷੋඇͰ Vuex ΛೖΕΔ͔ܾΊͳ͍ͰΈ߹ΘͤΔ• ͕ࣗؔΘΔϓϩδΣΫτݱࡏશͯ Vuex + ϩʔΧϧεςʔτͰӡ༻த
ʮVuex ΛΘͳ͍ͰരൃʯΛ͙(2)• ϩʔΧϧεςʔτΛશ͘Θͳ͍։ൃർฐ͢ΔɻͦΕΛΔͳΒ React Ͱྑ͍ͷͰ Vue ϩʔΧϧεςʔτΛ͏·͘ѻ͏ͷͱͯ͠͏͜ͱ• ϩʔΧϧεςʔτΛ͏͜ͱΛڐ༰͢ΔͱʮͦͷίϯϙʔωϯτͰ͔͠ΘΕͳ͍ʯͱ͍͏ঢ়ଶΛͬ͞͞ͱഁغͰ͖ΔͷͰ։ൃϨϕϧࠩҟΛٵऩͰ͖Δ• Vuex υϝΠϯͱࣄ࣮Λ Store ʹɺϓϨθϯςʔγϣϯͱঢ়ଶΛϩʔΧϧεςʔτʹ࣋ͨͤΔ͖• ͱ͍͑ͲͷΈͪVue ͷ RAM ༰ྔ͕େ͖͍ਓ͚ͷϑϨʔϜϫʔΫͳͷؒҧ͍ͳ͍
༨ஊ) Vuex Λͬͯരൃͤ͞Δํ๏• Single source of truth Λશʹ९क͢Δͱɺ Redux ΄Ͳ໊લۭؒΛࡉׂ͔͘͠ͳ͍߹্େମ state ͕ա࿑ࢮ͢Δ• createPostForm ͬͯதʹϑΥʔϜͷཁૉ͍ͬͺ͍ೖͬͯΔ͚Ͳߘ࡞ͬͯΔՕॴͱ͔5ݸҎ্͋Δ͠Ͳ͜ͷϑΥʔϜͩΑ• ϓϨθϯςʔγϣϯͷ߹͕Կނ͔υϝΠϯʹॻ͔Ε͍ͯͨΓͯ͠ഁ໓ͯ͘͠Δ• ϨΠϠʔ͚·͠ΐ͏
2 / 3
ʮσβΠφʔͰ৮ΕͯҰॹʹࣄͰ͖Δʯઆ
A. Ϛδদ
σβΠφʔͱҰॹʹࣄ͢Δͱരൃͨ͠Γ͠ͳ͔ͬͨΓ͢Δ
σβΠφʔͱҰॹʹࣄ͢Δͱരൃͨ͠Γ͠ͳ͔ͬͨΓ͢Δ(1)• ਖ਼σβΠφʔ + ϚʔΫΞοϓΤϯδχΞ͕Ͱ͖Δਓ Vue ίϯϙʔωϯτ͔͚Δ• ejs / erb / jade / Smarty / mustache ͱςϯϓϨʔτΤϯδϯΛ͖ͬͯͨϚʔΫΞοϓͷਓؒͰ͋Εॻ͘ʹ͋ͨͬͯԿͳ͍• ʮσβΠϯҰྲྀ͚ͩͲϚʔΫΞοϓෆ׳ΕʯͰ Scoped CSS Ͱष͍ͷʹ֖ΛͰ͖Δͷ࠷ߴ• ͜͜Ͱʮ͜͜Ͱ͔͠ΘΕ͍ͯͳ͍ͷʯΛ؆୯ʹഁغͰ͖Δࠩҟٵऩ͕ޮ͍ͯ͘Δ
σβΠφʔͱҰॹʹࣄ͢Δͱരൃͨ͠Γ͠ͳ͔ͬͨΓ͢Δ(2)• ͍͍͕ͩͨൃੜ͢Δͷ Node ڥͷͳͷͰڥͷߏஙߦ͢Δ• Storybook ͷ stories ͷॻ͖ํ·Ͱڭ͑ͯӠʑΧϯψϯ……ͱ͔Γͩ͢ͱటপԽ͢Δ• దͳ Sandbox ίϯϙʔωϯτΛ࡞Δ͔ stories FE ͕ॻ͍ͯͦ͜Ͱແݶʹॻ͍ͯΒͬͨ΄͏͕݁ՌతʹʹͳΔ• ςετΛॻ͍ͯͨΒςετͿͬյΕΔͷͰ͢• ͜Ε͑͞Εരൃ͠ͳ͍ʢςετരൃ͢Δ͔ʣ
3 / 3
Vue.js طଘͷ Web ΞϓϦͷΤοδར༻ JS ͱͯ͠࠷ڧઆ
A. ͍͍ͩͨ͋ͬͯΔ
Web ΞϓϦʹ Vue.js Λࠩ͠ࠐΉͱരൃ͠ͳ͘ͳΔ
Web ΞϓϦʹ Vue.js Λࠩ͠ࠐΉͱരൃ͠ͳ͘ͳΔ(1)ςϯϓϨʔτه๏͕ͦͦ͜͜ϞμϯͰ͍͍͢• αʔόʔαΠυத৺ͷ(Slim Blade ͳͲ͔Β HTML Λग़ྗ͍ͯ͠Δ)ϓϩδΣΫτʹҰ෦ JS ΛೖΕΔͳΒ Vue.js ࠷ߴ• [v-cloak] ΛͬͯςϯϓϨʔτͷ࿐ग़Λ͗ͭͭɺόοΫΤϯυͷςϯϓϨʔτΤϯδϯͱΈ߹Θ͍ͤ͢ͷ͕ૉఢʢΓ͗͢Δͱരൃ͢Δʣ• σϦϛλ( {{}} )Λࣗ༝ʹม͑ΒΕΔ( [[]] ͳͲ)ͷͰͲͷςϯϓϨʔτΤϯδϯͱ͔ͪ߹Θͳ͍
Web ΞϓϦʹ Vue.js Λࠩ͠ࠐΉͱരൃ͠ͳ͘ͳΔ(2)ঢ়ଶཧΛࡶʹͰ͖Δͷ͕ྑ͍• ํόΠϯσΟϯάΛར༻͢ΔͱదʹσʔλΛͿͪࠐΉͱదʹϦΞϧλΠϜͰө͞ΕΔ• this.setState() Έ͍ͨͳ֓೦͕ͳ͘ɺదʹάϩʔόϧʹঢ়ଶΛల։͢ΔͱͦΕ͚ͩͰετΞΛల։Ͱ͖Δ• window.store Λ࡞Γग़ͯ͠ബ͍ετΞΛ࡞Δͷ͕͓͢͢Ί
Web ΞϓϦʹ Vue.js Λࠩ͠ࠐΉͱരൃ͠ͳ͘ͳΔ(1)ϩʔΧϧεςʔτͱ͍͏֓೦͕͋ΔͷͰ new Vue ͍͢͠ͷ͕ྑ͍• ϩʔΧϧεςʔτΛڐ༰͢Δٕज़Ͱ͋ΔͨΊؾܰʹ new Vue Λͯ͠ബ͍ಠࣗετΞͱΈ߹ΘͤΔͱշదʹ։ൃ͕Ͱ͖Δ• SPA ͷ߹ Vuex ͕ͳ͍ͱരൃ͕ͨ͠ɺͪΐ͍ೖΕͳΒͦ͜·ͰΫϦςΟΧϧͳӨڹͳ͍• ଟ͘ͷॻ͖ํΛڐ༰͍ͯ͠ΔརΛ׆͔ͯ͠ϓϩδΣΫτنʹϚονͨ͠։ൃελΠϧΛऔΔͱடংΛ࡞Γ͍͢
ͦͷଞʹ……ҎԼͷ࣌ؒͷ߹্ΓࠐΉ༨༟͕ͳ͔ͬͨͷͰ࠙ձͰ• ϓϥάΠϯϧʔςΟϯάϑοΫ͕ΦϨΦϨߏͷ• utils σΟϨΫτϦ͕Ͱ͖ͨΓཧγεςϜ่͕յͯ͠രൃ͢Δ
ͦͷଞʹ……ҎԼͷ࣌ؒͷ߹্ΓࠐΉ༨༟͕ͳ͔ͬͨͷͰ࠙ձͰ• ϓϥάΠϯϧʔςΟϯάϑοΫ͕ΦϨΦϨߏͷ• utils σΟϨΫτϦ͕Ͱ͖ͨΓཧγεςϜ่͕յͯ͠രൃ͢Δ• utils ͷരൃͷŠŧŽˠ https://slides.com/potato4d/vuejs_meetup7
ͦͷଞʹ……ҎԼͷ࣌ؒͷ߹্ΓࠐΉ༨༟͕ͳ͔ͬͨͷͰ࠙ձͰ• Vue + TypeScript ͰͤʹͳΖ͏ͱ͢Δ• Vuex + TypeScript Ͱ mapGetters / mapActions ͕ any ʹͳͬͯരൃ͢Δ
ͦͷଞʹ……ҎԼͷ࣌ؒͷ߹্ΓࠐΉ༨༟͕ͳ͔ͬͨͷͰ࠙ձͰ• ςετ• ॳݟͰΔͱେମരൃ͢Δ
ͦͷଞʹฉ͍ͯΈ͍͓ͨؾܰʹͲ͏ͧ
Vue.js Λ৽نͰಋೖ͢Δ߹ʹબ͖͢͜ͱ
Vue.js Λ৽نͰಋೖ͢Δ߹ʹબ͖͢͜ͱ• SPA ฤ• SPA ͡Όͳ͍ฤ
SPA ฤ࠷ݶ͓͖ͬͯ͘͜ͱ• ಡΈऔΓઐ༻ͷΞϓϦέʔγϣϯͰͳ͍ݶΓ Vuex ඞͣಋೖ͢Δ• ΦϨΦϨϨΠϠʔΛ࡞Γग़ͦ͠͏ͳ෦ʹ͍ͭͯۃྗΑͦͷ࣮Λࢀߟʹͯ͠ʮॻ͍͔ͨͭ͠Θ͔Βͳ͍ʯΛආ͚Δ• σβΠφʔʹίϯϙʔωϯτΛ࡞ͬͯΒ͏ͱ͖ॻ͘·ͰͷϋʔυϧΛ࠷େݶԼ͛Δ• Nuxt.js Λ͏
ফͨ͘͠ͳ͍ͳΒ Nuxt.js
Nuxt.js ͱ• Vue based ͳϑϧελοΫϑϩϯτΤϯυϑϨʔϜϫʔΫ• SPA ઐ༻ɻͪΐ͍ೖΕෆՄɻ• Vue + Vue Router + Vuex + SSR ڥ͕σϑΥϧτ• ΦϨΦϨϓϥάΠϯϨΠϠʔͳͲ Nuxt.js ͕ٵऩ• نϕʔεͷΞʔΩςΫνϟʹΑͬͯنΛकΔͱ୭Ͱߴ࣭ͳίʔυ͕ॻ͚Δ
SPA ͚ͷ։ൃηοτ
Nuxt.js Λ͏ͱخ͍͜͠ͱ• ن͕ΦϨΦϨΞʔΩςΫνϟ͔ΒϓϩδΣΫτΛकͬͯ͘ΕΔ• ෭࢈ͱͯ͠ҎԼͷΑ͏ͳศརػೳ͕͍ͭͯ͘Δ• ϧʔςΟϯάͷࣗಈੜػೳʢϧʔςΟϯάཧ༻ͷϨΠϠΛফͤΔʣ• Vuex ετΞΛѻ͍͘͢͢ΔΦʔτϩʔσΟϯάʢಋೖ͕໘͡Όͳ͍ʣ• ๛ͳϓϥάΠϯʗΤίγεςϜ
खͬऔΓૣ͘େମͷΛղফͰ͖Δ
SPA Nuxt.js Ͱྑ͍
SPA ͡Όͳ͍ฤ• ͪΐ͍ೖΕͷ߹େମ͖ͬ͞·Ͱॻ͍ͨ௨Γ• ૉͳʮετΞύλʔϯʯͰ࣮͢Δ• ͲͷΈͪ jQuery ͷίʔυͳͲ͔ΒσʔλΛ͍͘͡Γճͨ͘͠ͳΔʢମݧஊʣͷͰ Readonly ΛੜΈग़͢ Vuex Θͳ͍• new Vue ({}) ͍ͭͯ͘͠ྑ͍ͷͰίϯϙʔωϯτಉ࢜ૄ݁߹Ͱ࡞Δ
SPA ͡Όͳ͍ฤ• ͜Ε͔Β࣮͢Δਓ͚ͷՃ Tips• Smarty, Slim, Blade ͳͲͱҰॹʹ͏ͳΒͰ͖Δ͚ͩҰͭͷ HTML ߏΛ͓ޓ͍ʹॻ͖͑ΔͷΊΔ• Λ༻ҙͯ͠ɺ $(‘#initialState’).innerHTML ͰऔΓग़ͯ͠ Vue ίϯϙʔωϯτʹྲྀ͠ࠐΉઃܭͰ࡞Δ
ऴΘΓʹ
Vue.js Մ೩ੑ
Ե4ͱ͔ͬͯΒΈ·͠ΐ͏
https://www.shoubo-shiken.or.jp/
Thank you!