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
moomoo-ya
February 19, 2019
Programming
0
1.9k
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.2k
はじめてのオンラインイベント配信 with COVID-19 バグ修正版 / Online-Event-bugfixed
moomooya
0
96
一番安い子だーれだ?~黒字化のための無慈悲なタスク配分~ / Distribute tasks
moomooya
1
2.9k
はじめてのオンラインイベント配信 with COVID-19 バグあり版 / Online-Event-includes-bug
moomooya
0
790
やはり俺のLT登壇はまちがっている。 / my-lightning-talk-is-wrong-as-i-expected
moomooya
4
2.1k
Gatsby.jsで.md/.adocが混在できるテンプレートを作ったときの苦しみ / Pain-to-create-gatsby-template-that-supports-markdown-and-asciidoc
moomooya
0
580
LADRのすすめ&先行技術検証PRJの紹介 / Introducing-LADR-and-Technology-verification
moomooya
5
2.3k
技術書へのアクセスを劇的に向上させた話 / oreilly-safari-and-acm-membership
moomooya
2
7.3k
モノリスにおけるビジネスロジックの設計 ~アグリゲートパターン~ / aggregate-pattern-for-domain-modeling-on-monolithic
moomooya
2
1.4k
Other Decks in Programming
See All in Programming
Bedrock Agentsレスポンス解析によるAgentのOps
licux
3
920
15分で学ぶDuckDBの可愛い使い方 DuckDBの最近の更新
notrogue
3
510
ナレッジイネイブリングにAIを活用してみる ゆるSRE勉強会 #9
nealle
0
160
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
230
5分で理解する SOLID 原則 #phpcon_nagoya
shogogg
1
300
Rails 1.0 のコードで学ぶ find_by* と method_missing の仕組み / Learn how find_by_* and method_missing work in Rails 1.0 code
maimux2x
1
200
Jakarta EE meets AI
ivargrimstad
0
340
機能が複雑化しても 頼りになる FactoryBotの話
tamikof
0
140
「個人開発マネタイズ大全」が教えてくれたこと
bani24884
1
190
Rubyと自由とAIと
yotii23
6
1.7k
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
680
Djangoにおける複数ユーザー種別認証の設計アプローチ@DjangoCongress JP 2025
delhi09
PRO
4
470
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
How to Think Like a Performance Engineer
csswizardry
22
1.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Typedesign – Prime Four
hannesfritz
40
2.5k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
370
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Thoughts on Productivity
jonyablonski
69
4.5k
Agile that works and the tools we love
rasmusluckow
328
21k
Fireside Chat
paigeccino
34
3.2k
4 Signs Your Business is Dying
shpigford
182
22k
A Tale of Four Properties
chriscoyier
158
23k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
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 • ॳͪ͜ΒͷଘࡏΛΒͳ͔ͬͨͷͰۤ͠ΜͰ͍Δ
͋Γ͕ͱ͏͍͟͝·ͨ͠