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
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
170
一番安い子だーれだ?~黒字化のための無慈悲なタスク配分~ / Distribute tasks
moomooya
1
3.6k
はじめてのオンラインイベント配信 with COVID-19 バグあり版 / Online-Event-includes-bug
moomooya
0
910
やはり俺の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
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
180
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
410
sbt 2.0: takeoff
eed3si9n
0
160
Performance Optimization With LLMs
xleitix
0
160
Workers Cache を知る
syumai
0
370
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
380
Simple Storage Service(S3) is not simple
iwatsukayura
0
290
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
280
Agents on Rails - Rails at Scale 2026
irinanazarova
0
570
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
800
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
Featured
See All Featured
Designing for humans not robots
tammielis
254
26k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
480
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
1k
ラッコキーワード サービス紹介資料
rakko
1
5.4M
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
2
2k
Technical Leadership for Architectural Decision Making
baasie
3
600
KATA
mclloyd
PRO
35
16k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
790
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
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 • ॳͪ͜ΒͷଘࡏΛΒͳ͔ͬͨͷͰۤ͠ΜͰ͍Δ
͋Γ͕ͱ͏͍͟͝·ͨ͠