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.1k
「オブジェクト指向」を再考する / 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
선언형 UI에서의 상태관리
l2hyunwoo
0
270
BEエンジニアがFEの業務をできるようになるまでにやったこと
yoshida_ryushin
0
200
テストコードのガイドライン 〜作成から運用まで〜
riku929hr
7
1.4k
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
300
ErdMap: Thinking about a map for Rails applications
makicamel
1
660
カンファレンス動画鑑賞会のススメ / Osaka.swift #1
hironytic
0
170
chibiccをCILに移植した結果 (NGK2025S版)
kekyo
PRO
0
130
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
4
250
ecspresso, ecschedule, lambroll を PipeCDプラグインとして動かしてみた (プロトタイプ) / Running ecspresso, ecschedule, and lambroll as PipeCD Plugins (prototype)
tkikuc
2
1.9k
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
770
Fibonacci Function Gallery - Part 2
philipschwarz
PRO
0
210
Beyond ORM
77web
11
1.6k
Featured
See All Featured
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Done Done
chrislema
182
16k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
The Language of Interfaces
destraynor
155
24k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
870
Building an army of robots
kneath
302
45k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
For a Future-Friendly Web
brad_frost
176
9.5k
Producing Creativity
orderedlist
PRO
343
39k
Thoughts on Productivity
jonyablonski
68
4.4k
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