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
複雑なv-ifに負けないために.pdf
Search
philomagi
September 19, 2019
Programming
1
1k
複雑なv-ifに負けないために.pdf
サンプルアプリの実装は以下
https://github.com/tooppoo/sample-for--vue-with-complex-conditions
philomagi
September 19, 2019
Tweet
Share
More Decks by philomagi
See All by philomagi
ドメイン駆動設計のホーリズム的側面 / domain-driven-design and holism
tooppoo
0
160
アート、サイエンス、「わかりやすさ」 / art, science, "easy to understand"
tooppoo
1
20k
ソフトウェアと「動的平衡」 / software-and-dynamic-equilibrium
tooppoo
1
900
javascriptでも条件式を使いたい話 / want to use conditional expression in javascript
tooppoo
0
6.2k
Fat ComponentにしないためのWebフロントエンド設計 / Web Front-End design to avoid being a Fat Component
tooppoo
4
3.4k
技術書・方法論とのお付き合い / how to learn theory
tooppoo
4
1.2k
「オブジェクト指向」を再考する / reconsider "object-oriented"
tooppoo
2
770
「モデル」の二面性と設計を考える / dual nature of "model"
tooppoo
2
1.6k
「ドメイン」駆動で考える「ドメイン駆動設計」/consideration of domain-driven design via domain
tooppoo
9
2.7k
Other Decks in Programming
See All in Programming
CloudNativePGがCNCF Sandboxプロジェクトになったぞ! 〜CloudNativePGの仕組みの紹介〜
nnaka2992
0
200
定理証明プラットフォーム lapisla.net
abap34
1
670
DROBEの生成AI活用事例 with AWS
ippey
0
110
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
11
1.6k
Swiftコンパイラ超入門+async関数の仕組み
shiz
0
200
Pulsar2 を雰囲気で使ってみよう
anoken
0
160
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
1
200
Amazon Nova Reelの可能性
hideg
0
270
Linux && Docker 研修/Linux && Docker training
forrep
23
4.2k
Writing documentation can be fun with plugin system
okuramasafumi
0
110
【PHP】破壊的バージョンアップと戦った話〜決断と説得
satoshi256kbyte
0
110
Simple組み合わせ村から大都会Railsにやってきた俺は / Coming to Rails from the Simple
moznion
3
3.9k
Featured
See All Featured
The Cult of Friendly URLs
andyhume
78
6.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.3k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
Gamification - CAS2011
davidbonilla
80
5.1k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Designing for humans not robots
tammielis
250
25k
Practical Orchestrator
shlominoach
186
10k
Optimising Largest Contentful Paint
csswizardry
33
3k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
280
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Fireside Chat
paigeccino
34
3.2k
Transcript
複雑なv-ifに負けないために 1 @Philomagi 2019/09/
[email protected]
#1 #yumemi_vue
発表者 @Philomagi • 主にフロントエンド主体のWEB系エンジニア • ScalaとTypescriptとRubyが好き ◦ Rubyは最近、公私共に若干疎遠 • PHPは中々縁が切れない悪友
◦ 最近は、「然程悪いやつでもないな」と思い始めてる 2
今回のお題 3
v-if 4
v-if =「表示条件」 5
6 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else> fuga
</div> </div> </template>
7 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else> fuga
</div> </div> </template>
v-ifを使うことで、 条件に応じて表示を変えられる 8
簡単!便利! 9
10 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else> fuga
</div> </div> </template>
<template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else> fuga </div>
</div> </template> 11 1. hoge/fuga の他に、piyoという表示もしたい 2. fugaを表示する条件を追加してほしい 3. hogeでもfugaでも無い場合に、 piyoを表示したい
12 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else-if="shouldShowFuga"> fuga
</div> <div v-else> piyo </div> </div> </template>
13 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else-if="shouldShowFuga"> fuga
</div> <div v-else> piyo </div> </div> </template>
条件の追加も簡単! 14
おしまい 15
おしまい 16
ご清聴ありがとうございました 17 しばらく後・・・
18 <template> <div> <div v-if="shouldShowHoge"> hoge </div> <div v-else-if="shouldShowFuga"> fuga
</div> <div v-else-if="shouldShowPiyo"> piyo </div> <div v-else-if="shouldShowXXX"> xxx </div> <div v-else-if="shouldShowYYY"> yyy </div> <div v-else-if="shouldShowZZZ"> zzz </div>
19 <script> export default { data() { return { shouldShowHoge:
/**/, shouldShowFuga: /**/, shouldShowPiyo: /**/, shouldShowXXX: /**/, shouldShowYYY: /**/, shouldShowZZZ: /**/, /* 以下略 */ } }, } </script>
20 <script> export default { data() { return { shouldShowHoge:
/**/, shouldShowFuga: /**/, shouldShowPiyo: /**/, shouldShowXXX: /**/, shouldShowYYY: /**/, shouldShowZZZ: /**/, /* 以下略 */ } }, } </script> 実際のプロジェクトでは • computedによる計算が必要だったり • 処理の中で状態が書き換えられたり 「条件」と「表示」の関係が さらに複雑になってくる
出てくる問題 表示の条件が複雑になると 21
表示の条件が複雑になると • htmlもjsも肥大化する 出てくる問題 22
出てくる問題 表示の条件が複雑になると • htmlもjsも肥大化する ◦ テストが大変 23
出てくる問題 表示の条件が複雑になると • htmlもjsも肥大化する ◦ テストが大変 ◦ 影響範囲を把握しづらく、修正しにくい 24
どうにか解決したい 25
問題を整理する 何故html/jsが肥大化するのか? 26
問題を整理する 何故html/jsが肥大化するのか? • 条件分岐がたくさん有るから • 条件毎に表示すべき内容が違うから 27
問題を整理する 何故html/jsが肥大化するのか? • 条件分岐がたくさん有るから • 条件毎に表示すべき内容が違うから 「条件」と「表示」を、 一つにまとめてしまってはどうだろう? 28
「条件」が決まれば「表示」も一意に定まる 「条件」と「表示」を一つにする 29
「条件」が決まれば「表示」も一意に定まる なら、「条件」と「表示」は 常にセットにして扱った方が便利なのでは? 「条件」と「表示」を一つにする 30
「条件」が決まれば「表示」も一意に定まる なら、「条件」と「表示」は 常にセットにして扱った方が便利なのでは? 「条件」と「表示」の対応関係を 1つのオブジェクトで表現してみる 「条件」と「表示」を一つにする 31
具体的にコードでは? 32
33 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export
interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean }
34 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export
interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean } 「表示」を表すプロパティ定義
35 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export
interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean } 「条件」を表すメソッド定義
36 2. コンポーネントを作る <template> <img alt="Vue logo" src="../../assets/logo.png"> </template>
37 3. 条件/表示の対応オブジェクトを実装する import { ShowImageSpec, ShowImageSpecParam } from '../show-image-spec'
import VueComp from '../../../frame-work/Vue.vue' export default class ShowVueSpec implements ShowImageSpec { readonly shown = VueComp isSatisfiedBy (param: ShowImageSpecParam ): boolean { return param.framework === 'Vue' } }
38 3. 条件/表示の対応オブジェクトを実装する import { ShowImageSpec, ShowImageSpecParam } from '../show-image-spec'
import VueComp from '../../../frame-work/Vue.vue' export default class ShowVueSpec implements ShowImageSpec { readonly shown = VueComp isSatisfiedBy (param: ShowImageSpecParam ): boolean { return param.framework === 'Vue' } } 「表示」の内容
39 3. 条件/表示の対応オブジェクトを実装する import { ShowImageSpec, ShowImageSpecParam } from '../show-image-spec'
import VueComp from '../../../frame-work/Vue.vue' export default class ShowVueSpec implements ShowImageSpec { readonly shown = VueComp isSatisfiedBy (param: ShowImageSpecParam ): boolean { return param.framework === 'Vue' } } 「表示」の内容 「表示」されるべき条件
40 4. オブジェクトから「表示」を得る get frameworkView (): VueConstructor { const appliedSpec:
ShowImageSpec = applyWithDefault( new ShowKoujichuSpec(), [ new ShowVueSpec(), new ShowHogeSpec() ] ) return appliedSpec.shown } 「表示」を取得
41 5. 得た「表示」を適用する <div> <h2>好きなjsのフレームワークは?</h2> <component :is="frameworkView" /> </div>
42 5. 得た「表示」を適用する <div> <h2>好きなjsのフレームワークは?</h2> <component :is="frameworkView" /> </div>
43 5. 得た「表示」を適用する <div> <h2>好きなjsのフレームワークは?</h2> <component :is="frameworkView" /> </div>
44 5. 得た「表示」を適用する <div> <h2>好きなjsのフレームワークは?</h2> <component :is="frameworkView" /> </div> is属性にVueConstructorを渡すと、
そのVueコンポーネントをレンダリングしてくれる!
45 https://jp.vuejs.org/v2/guide/components.html
46 https://jp.vuejs.org/v2/guide/components.html
サンプルアプリ (スライドのdescriptionに記載) 47
「条件」に対する考え方 48
コンポーネントだけで頑張らない 49 • Vue.jsのSingle File Componentは便利だけど、 その中で全て完結させる必要は無い • 「表示」について複雑な条件やルールが有るなら、 それも立派な「ロジック」と考えた方が良い
• OOPのテクニックを使えば、コンポーネントも より柔軟かつシンプルにできる
フロントにも「ロジック」は有る 50 • 「表示」はコンポーネントに、 「ロジック」は専門のモジュールに任せる • 責務・関心を適切に分割しよう
まとめ • 複雑な表示条件はコンポーネントだけで頑張ら ず、「ロジック」として独立させる • OOPのテクニックを使うことで より柔軟なコンポーネントにできる • 責務と関心を適切に分離する 51
ご清聴ありがとうございました 52