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
Vue.js を初めてプロダクトに導入して直面した課題と得られた幸せ
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
moomoo-ya
February 19, 2019
Programming
0
2.2k
Vue.js を初めてプロダクトに導入して直面した課題と得られた幸せ
RAKUS Meetup Tokyo #2
2019.2.19
moomoo-ya
February 19, 2019
Tweet
Share
More Decks by moomoo-ya
See All by moomoo-ya
サービスを陳腐化させない組織だった技術刷新 / Technology Renewal Initiatives
moomooya
0
1.5k
はじめてのオンラインイベント配信 with COVID-19 バグ修正版 / Online-Event-bugfixed
moomooya
0
130
一番安い子だーれだ?~黒字化のための無慈悲なタスク配分~ / Distribute tasks
moomooya
1
3.3k
はじめてのオンラインイベント配信 with COVID-19 バグあり版 / Online-Event-includes-bug
moomooya
0
860
やはり俺のLT登壇はまちがっている。 / my-lightning-talk-is-wrong-as-i-expected
moomooya
4
2.5k
Gatsby.jsで.md/.adocが混在できるテンプレートを作ったときの苦しみ / Pain-to-create-gatsby-template-that-supports-markdown-and-asciidoc
moomooya
0
670
LADRのすすめ&先行技術検証PRJの紹介 / Introducing-LADR-and-Technology-verification
moomooya
5
2.8k
技術書へのアクセスを劇的に向上させた話 / oreilly-safari-and-acm-membership
moomooya
2
7.7k
モノリスにおけるビジネスロジックの設計 ~アグリゲートパターン~ / aggregate-pattern-for-domain-modeling-on-monolithic
moomooya
2
1.7k
Other Decks in Programming
See All in Programming
Fluid Templating in TYPO3 14
s2b
0
120
AtCoder Conference 2025
shindannin
0
1k
2年のAppleウォレットパス開発の振り返り
muno92
PRO
0
200
Vibe Coding - AI 驅動的軟體開發
mickyp100
0
170
Smart Handoff/Pickup ガイド - Claude Code セッション管理
yukiigarashi
0
110
CSC307 Lecture 06
javiergs
PRO
0
680
CSC307 Lecture 05
javiergs
PRO
0
490
プロダクトオーナーから見たSOC2 _SOC2ゆるミートアップ#2
kekekenta
0
180
Apache Iceberg V3 and migration to V3
tomtanaka
0
130
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
440
Implementation Patterns
denyspoltorak
0
270
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.8k
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
698
190k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
72
The World Runs on Bad Software
bkeepers
PRO
72
12k
What does AI have to do with Human Rights?
axbom
PRO
0
2k
Testing 201, or: Great Expectations
jmmastey
46
8k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.7k
How GitHub (no longer) Works
holman
316
140k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Marketing to machines
jonoalderson
1
4.6k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
370
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
200
Deep Space Network (abreviated)
tonyrice
0
42
Transcript
Vue.js ΛॳΊͯϓϩμΫτʹಋ ೖͯ͠໘ͨ͠՝ͱಘΒΕͨ ͤ @moomooya Isamu Suzuki, Rakus 2019.2.19
ླ ༐ʢ͖ͣ͢ ͍͞Ήʣ • ւಓग़ 35ࡀ • QiitaͰษڧձϨϙ࠷ΦδαϯΛࢦ͍ͯ͠·͢ • ओʹMicroservicesͱ͔JavaScriptؔ࿈த৺
• झຯ • ITωλͷΞφϩάήʔϜ੍࡞ • ࣾΨϯϓϥ෦෦ • ITۀքଟΊͷαόήओ࠵ @moomooya @moomoo-ya
ུྺ • ߴߍʙେֶʙ৽ଔ • ߴߍͰϓϩάϥϜίϯςετք۾Λ͏Ζ͏Ζ • IPAʢ࣌௨࢈লʣͷࢿ֨औΓ͋͞Γ • େखSIer ࣌
• ূ݊/֎ࠃҝସγεςϜͷ্ྲྀ͔ΒԼྲྀ·Ͱ • อݥਃࠐΈγεςϜͷ৽ن։ൃɺͳͲ • খنϕϯνϟʔΛܦ༝ͯ͠ϥΫε • ɹɹɹɹɹɹͷαʔϏε։࢝ • ΤϯδχΞจԽͷ͔͠ɺͳͲ • ৽نαʔϏε։ൃ ←ࠓ͜Εͷ͜ͱΛ͠·͢
ຊ
ϓϩμΫτʹ Vue.js ಋೖͯ͠ Ϳ͔ͭͬͨ՝Λڞ༗͠·͢ ະղܾ՝͋Γ·͢
1. Ξϩʔԋࢉࢠ͑ͳ͍෦͕͋Δ
ࠓ͔ΒJavaScriptॻ͘ͳΒ ES2015+ ͔ TypeScript
ؔఆٛΞϩʔԋࢉࢠ () => {}
VueίϯϙʔωϯτͰ جຊతʹΞϩʔԋࢉࢠ͑ͳ͍
͜Ε͕NG <template> <!-- ... --> </template> <script> export default {
// ... methods: { changeText: () => { this.text = "foobar"; } } } </script> VueΠϯελϯεΛࢦ͢ ͕ࢀরͰ͖ͳ͍ this
͜ΕͳΒOK <template> <!-- ... --> </template> <script> export default {
// ... methods: { changeText() { this.text = "foobar"; } } } </script> ࣍ظv3ͰͷରԠʹ ظ͠·͠ΐ͏
2. ΦϒδΣΫτͷߋ৽ํ๏
Vue.js ͱ͍͑ ϦΞΫςΟϒγεςϜ
JavaScriptΦϒδΣΫτͷߋ৽Ͱ Ϗϡʔ͕ࣗಈߋ৽͞ΕΔ
ͱͯศརɺ͘͢͝
੍ͨͩ͋͠Δ • VueΠϯελϯε͕ॳظԽ͞ΕΔͱ͖ʹ ͞ΕͨJSΦϒδΣΫτʹରͯ͠ Object.definePropertyؔͰgetter/setterΛͭ͘Δ • ͜ΕΒͷΞΫηοαΛར༻ͯ͠มߋݕΛ͢Δ
͜ΕOK <template> <!-- ༩͑ΒΕͨΦϒδΣΫτ͔Β จࣈྻग़ྗ͢Δίϯϙʔωϯτ --> <text-output v-bind:data="textObject" /> <button
v-on:click=“changeText()"> จࣈྻΛม͑Δ </button> </template> <script> export default { data() { return { textObject: { value: "ग़ྗ͢Δจࣈྻ", size: 16 } }; }, methods: { changeText() { this.textObject.value = "มߋͨ͠จࣈྻ"; } } }; </script> ॳظʹ͋ΔΛૢ࡞
͜ΕOK <template> <!-- ༩͑ΒΕͨΦϒδΣΫτ͔Β จࣈྻग़ྗ͢Δίϯϙʔωϯτ --> <text-output v-bind:data="textObject" /> <button
v-on:click=“changeText()"> จࣈྻΛม͑Δ </button> </template> <script> export default { data() { return { textObject: { value: "ग़ྗ͢Δจࣈྻ", size: 16 } }; }, methods: { changeText() { this.textObject.value = "มߋͨ͠จࣈྻ"; } } }; </script> ॳظʹ͋Δ ॻ͖͑Εը໘ʹө͞ΕΔ ॳظʹ͋ΔΛૢ࡞
͜ΕNG <template> <!-- ༩͑ΒΕͨΦϒδΣΫτ͔Β จࣈྻग़ྗ͢Δίϯϙʔωϯτ --> <text-output v-bind:data="textObject" /> <button
v-on:click=“setSize()”> αΠζΛઃఆ͢Δ </button> </template> <script> export default { data() { return { textObject: { value: "ग़ྗ͢Δจࣈྻ" } }; }, methods: { setSize() { this.textObject.size = 16; } } }; </script> ॳظʹͳ͍Λૢ࡞
͜ΕNG <template> <!-- ༩͑ΒΕͨΦϒδΣΫτ͔Β จࣈྻग़ྗ͢Δίϯϙʔωϯτ --> <text-output v-bind:data="textObject" /> <button
v-on:click=“setSize()”> αΠζΛઃఆ͢Δ </button> </template> <script> export default { data() { return { textObject: { value: "ग़ྗ͢Δจࣈྻ" } }; }, methods: { setSize() { this.textObject.size = 16; } } }; </script> ॳظʹͳ͍ Ճͯ͠มߋ͕ݕ͞Εͳ͍ ໌ࣔతʹ this.$set(this.textObject, “size”, 16); ॳظʹͳ͍Λૢ࡞
3. ཁૉ໊ͷিಥ
vueϥΠϒϥϦ͕ ͲΜͲΜඋ͞Ε͍ͯΔ
ϥΠϒϥϦͷཁૉ໊ॏෳ • ϚςϦΞϧσβΠϯͳUIϥΠϒϥϦͷVuetify • <v-image>ͱ͔<v-select>ͱ͔ͰΦγϟϨUI࡞ΕΔ • Canvasૢ࡞ϥΠϒϥϦͷKonvaΛϥοϓͨ͠vue-konva • ը૾ΦϒδΣΫτΛ<v-image>Ͱࢦఆ͢Δ
ϥΠϒϥϦͷཁૉ໊ॏෳ • ϚςϦΞϧσβΠϯͳUIϥΠϒϥϦͷVuetify • <v-image>ͱ͔<v-select>ͱ͔ͰΦγϟϨUI࡞ΕΔ • Canvasૢ࡞ϥΠϒϥϦͷKonvaΛϥοϓͨ͠vue-konva • ը૾ΦϒδΣΫτΛ<v-image>Ͱࢦఆ͢Δ
<v-image> ॏෳ
ಈ࡞͠·ͤΜͰͨ͠
ཁૉ໊ͷϧʔϧ • Vue.js ελΠϧΨΠυ https://jp.vuejs.org/v2/style-guide/index.html
͍͓ͪ͏ճආͰ͖ΔͬΆ͍ॻ͖ํ ࣌ʮผ໊Λ͚ͭΔʯΓํ͕͔Βͣ٧ΜͰ͍ͨ <script> import ComponentA from "@/components/hoge/ComponentA"; import ComponentA2 from
"@/components/fuga/ComponentA"; export default { components: { "hoge-comp-a": ComponentA, "fuga-comp-a": ComponentA2 } } </script> ಛʹ͜ͷॻ͖ํ }
4. ηΦϦʔΘ͔Βͳ͍
ϓϩμΫτͰ࡞Δͱ େྔͷ໋໊ɺϞδϡʔϧׂΛ ରॲ͠ͳ͚ΕͳΒͳ͍
camelCaseͳͷ͔ PascalCaseͳͷ͔ kebab-caseͳͷ͔
ϞδϡʔϧڥքΛ Ͳ͜ʹҾ͚͍͍ͷ͔
Vue.js υΩϡϝϯτ͕ ॆ࣮͍ͯ͠Δ
ελΠϧΨΠυ͕͋ΔͷͰ·ͣख़ಡ • Vue.js ελΠϧΨΠυʢެࣜʣ • https://jp.vuejs.org/v2/style-guide/ • Vue.js ίϯϙʔωϯτ ελΠϧΨΠυ
• https://pablohpsilva.github.io/vuejs-component- style-guide/#/japanese • ॳͪ͜ΒͷଘࡏΛΒͳ͔ͬͨͷͰۤ͠ΜͰ͍Δ
5. Vuex ͍͗͢
ηΦϦʔ͕Θ͔Βͳ͔ͬͨ݁Ռ
Vuex ʹա࣮
Vuex(Flux)ͷΞʔΩςΫνϟ https://vuex.vuejs.org/ja/
Vuexͷ࣮ηΦϦʔ • State • ঢ়ଶΛอଘ͢ΔʢάϩʔόϧͬΆ͍มྖҬʣ • ໌Β͔ʹଟ༻ͨ͠Βμϝͳงғؾ • Mutation ؔ܈
• State Λߋ৽͢Δ།Ұͷॲཧ܈ • ಉظॲཧతʹ࣮͢Δ • Action ؔ܈ • ඇಉظॲཧΛ࣮ͯ͠Α͍ • State ͷߋ৽ Mutation ܦ༝
Vuexͷ࣮ηΦϦʔ • State • ঢ়ଶΛอଘ͢ΔʢάϩʔόϧͬΆ͍มྖҬʣ • ໌Β͔ʹଟ༻ͨ͠Βμϝͳงғؾ • Mutation ؔ܈
• State Λߋ৽͢Δ།Ұͷॲཧ܈ • ಉظॲཧతʹ࣮͢Δ • Action ؔ܈ • ඇಉظॲཧΛ࣮ͯ͠Α͍ • State ͷߋ৽ Mutation ܦ༝ ←͜ΕΛ֦େղऍͯ͠͠·ͬͨ
ඇಉظσʔλऔಘॲཧΛ ͯ͢VuexͰ࣮
ઈࢍҾ͖ฦ͠த
ίϯϙʔωϯτʹด͡Δͷ ඇಉظॲཧͰίϯϙʔωϯτʹ هड़͢ΕΑ͍
6. ෆదͳmixins
Vueίϯϙʔωϯτʹ v-model ଐੑͱ͍͏ ศརͳଐੑ͕͋Γ·͢
Vue.jsͷίϯϙʔωϯτؒ௨৴ • ίϯϙʔωϯτ͔Β • v-bind:ϓϩύςΟ໊ Ͱ͢ • v-on:Πϕϯτ໊ Ͱड͚औΔ <blog-post
v-for="post in posts" v-bind:key="post.id" v-on:on-change="onChange" > </blog-post>
Vue.jsͷίϯϙʔωϯτؒ௨৴ • ࢠίϯϙʔωϯτ • props ϓϩύςΟʹఆٛͯ͠ड͚औΔ • this.$emit ͰΠϕϯτૹ৴ͯ͠ฦ͢ props:
{ key: { type: Number, default: 0 } }, methods: { onChange(value) { this.$emit("on-change", value); } }
v-modelͱ • ϓϩύςΟ໊ͱΠϕϯτ໊Λݻఆͨ͠ҥߏจ • ड͚͢ϓϩύςΟ໊Λ value • ฦ͢ΠϕϯτΛ input <blog-post
v-bind:value="post.id" v-on:input="post.id = $event.target.value" > </blog-post> <blog-post v-model="post.id"> </blog-post>
v-modelͱ • ϓϩύςΟ໊ͱΠϕϯτ໊Λݻఆͨ͠ҥߏจ • ड͚͢ϓϩύςΟ໊Λ value • ฦ͢ΠϕϯτΛ input <blog-post
v-bind:value="post.id" v-on:input="post.id = $event.target.value" > </blog-post> <blog-post v-model="post.id"> </blog-post> ͨͩ͜͠Ε ίϯϙʔωϯτͷͳ͠
v-modelରԠͳࢠίϯϙʔωϯτ • ຖճ͜ΕΛॻ͔ͳ͍ͱ͍͚ͳ͍ export default { props: { value: {
type: String, default: undefined } }, methods: { onInput(value) { this.$emit("input", value); } } }
v-modelରԠͳࢠίϯϙʔωϯτ • ຖճ͜ΕΛॻ͔ͳ͍ͱ͍͚ͳ͍ export default { props: { value: {
type: String, default: undefined } }, methods: { onInput(value) { this.$emit("input", value); } } } ϛοΫεΠϯͰ ·ͱΊͨΖ
͜͜·ͩݕূதͰ͢
propsΛmixins͢Δͷμϝͦ͏ • mixinsΛղܾ͢Δ·ͰͷҰॠvalue͕undefinedʹͳΔ • templateͰ͍ͬͯΔͱίϯιʔϧΤϥʔ͕ग़Δ • slotͱ͔͏·ͬͨ͘Βڞ௨ԽͰ͖Δ͔͠Εͳ͍ • ↑ࢼ͍ͤͯ·ͤΜ •
ੈؒͷUIϥΠϒϥϦͷιʔεΛݟͨײͩ͡ͱ ͜͜ڞ௨Խ͠ͳ͍ͷ͕ηΦϦʔͳؾ͕͍ͯ͠Δ
ͰτʔλϧͰ ಋೖͯͤ͠ʹͳ͍ͬͯ·͢
ྑ͍ͱ͜Ζαϥοͱ
1. ୯ҰϑΝΠϧίϯϙʔωϯτ
DOMͱॲཧͱελΠϧΛ·ͱΊΒΕͯૉఢ • ҙຯͷ͋Δ୯ҐͰѻ͑Δ • CSS͕ scoped Ͱ1ϑΝΠϧʹ ดͯ͡ద༻Ͱ͖Δ • ίʔυ͕ංେԽ͠ʹ͍͘
<template> <blog-post class="title" v-model="title" /> </template> <script> export default { data() { title: "λΠτϧ"; } }; </script> <style scoped> .title { font-size: large; } </style>
2. υΩϡϝϯτ͕ૉΒ͍͠
͜͜·Ͱࢀর͍ͯ͠Δ υΩϡϝϯτ ͯ͢ຊޠԽࡁΈ
தؖͳͲΞδΞݍͰྲྀߦ͍ͬͯΔΒ͍͠
ΞδΞݍͰྲྀߦ͍ͬͯΔ ϑϨʔϜϫʔΫ……͏ͬɺ಄͕ Seasar2
3. React + Flux ͷܦݧϜμʹͳΒͳ͍
Vue.js ͷঢ়ଶཧ Vuex FluxΞʔΩςΫνϟ
ʮ͔ͬͨ͜͡ͱ͕͋ΔʯఔͰ ཧղͷॿ͚ʹͳΓ·ͨ͠
·ͱΊ
ελΠϧΨΠυ͕͋ΔͷͰ·ͣख़ಡ • Vue.js ελΠϧΨΠυʢެࣜʣ • https://jp.vuejs.org/v2/style-guide/ • Vue.js ίϯϙʔωϯτ ελΠϧΨΠυ
• https://pablohpsilva.github.io/vuejs-component- style-guide/#/japanese • ॳͪ͜ΒͷଘࡏΛΒͳ͔ͬͨͷͰۤ͠ΜͰ͍Δ
͋Γ͕ͱ͏͍͟͝·ͨ͠