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
Vue.js を初めてプロダクトに導入して直面した課題と得られた幸せ
Search
moomoo-ya
February 19, 2019
Programming
2.3k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Vue.js を初めてプロダクトに導入して直面した課題と得られた幸せ
RAKUS Meetup Tokyo #2
2019.2.19
moomoo-ya
February 19, 2019
Transcript
67 slides
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 • ॳͪ͜ΒͷଘࡏΛΒͳ͔ͬͨͷͰۤ͠ΜͰ͍Δ
͋Γ͕ͱ͏͍͟͝·ͨ͠
More Decks by moomoo-ya
See All by moomoo-ya
サービスを陳腐化させない組織だった技術刷新 / Technology Renewal Initiatives
moomooya
0
1.7k
はじめてのオンラインイベント配信 with COVID-19 バグ修正版 / Online-Event-bugfixed
moomooya
0
180
一番安い子だーれだ?~黒字化のための無慈悲なタスク配分~ / Distribute tasks
moomooya
1
3.6k
はじめてのオンラインイベント配信 with COVID-19 バグあり版 / Online-Event-includes-bug
moomooya
0
920
やはり俺のLT登壇はまちがっている。 / my-lightning-talk-is-wrong-as-i-expected
moomooya
4
2.7k
Gatsby.jsで.md/.adocが混在できるテンプレートを作ったときの苦しみ / Pain-to-create-gatsby-template-that-supports-markdown-and-asciidoc
moomooya
0
730
LADRのすすめ&先行技術検証PRJの紹介 / Introducing-LADR-and-Technology-verification
moomooya
5
3.1k
技術書へのアクセスを劇的に向上させた話 / oreilly-safari-and-acm-membership
moomooya
2
8k
モノリスにおけるビジネスロジックの設計 ~アグリゲートパターン~ / aggregate-pattern-for-domain-modeling-on-monolithic
moomooya
2
1.8k
Other Decks in Programming
See All in Programming
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
340
[Kotlin Fest 2026] eBPF Tracing for Kotlin
takehaya
0
120
느린 네트워크와 저사양 디바이스 사용자를 위한 웹뷰 로딩 시간 개선기
kmkim
1
230
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
420
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
2.1k
AI Augmentation Techniques with Liberty
ivargrimstad
1
470
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
180
Goコンパイラを作ってGoをもっと理解する / Build a Go compiler to better understand Go
ikura_hamu
0
130
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
3
1.7k
Seven New Principles of Software Engineering
yegor256
0
490
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
6
1.5k
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
250
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.7k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
30 Presentation Tips
portentint
PRO
1
470
Context Engineering - Making Every Token Count
addyosmani
9
1.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.9k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2.1k
It's Worth the Effort
3n
188
29k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
480
4 Signs Your Business is Dying
shpigford
187
23k
Leo the Paperboy
mayatellez
11
2.5k
Building an army of robots
kneath
307
47k