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.2k
1
Share
複雑なv-ifに負けないために.pdf
サンプルアプリの実装は以下
https://github.com/tooppoo/sample-for--vue-with-complex-conditions
philomagi
September 19, 2019
More Decks by philomagi
See All by philomagi
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
3
1.7k
なぜ定義は問題解決に直結するのか/why-definitions-are-linked-to-problem-solving-with-tdd
tooppoo
0
81
ドメイン駆動設計のホーリズム的側面 / domain-driven-design and holism
tooppoo
0
210
アート、サイエンス、「わかりやすさ」 / art, science, "easy to understand"
tooppoo
1
21k
ソフトウェアと「動的平衡」 / software-and-dynamic-equilibrium
tooppoo
1
1.1k
javascriptでも条件式を使いたい話 / want to use conditional expression in javascript
tooppoo
0
6.6k
Fat ComponentにしないためのWebフロントエンド設計 / Web Front-End design to avoid being a Fat Component
tooppoo
4
3.8k
技術書・方法論とのお付き合い / how to learn theory
tooppoo
4
1.3k
「オブジェクト指向」を再考する / reconsider "object-oriented"
tooppoo
2
870
Other Decks in Programming
See All in Programming
L’IA au service des devs : Anatomie d'un assistant de Code Review
toham
0
240
Coding as Prompting Since 2025
ragingwind
0
830
KagglerがMixSeekを触ってみた
morim
0
380
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
210
의존성 주입과 모듈화
fornewid
0
130
今こそ押さえておきたい アマゾンウェブサービス(AWS)の データベースの基礎 おもクラ #6版
satoshi256kbyte
1
240
メッセージングを利用して時間的結合を分離しよう #phperkaigi
kajitack
3
590
実用!Hono RPC2026
yodaka
2
140
Running Swift without an OS
kishikawakatsumi
0
800
おれのAgentic Coding 2026/03
tsukasagr
1
140
How We Benchmarked Quarkus: Patterns and anti-patterns
hollycummins
1
120
実践ハーネスエンジニアリング #MOSHTech
kajitack
7
6.4k
Featured
See All Featured
How to Ace a Technical Interview
jacobian
281
24k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Design in an AI World
tapps
0
190
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
110k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.1k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
170
The Language of Interfaces
destraynor
162
26k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Documentation Writing (for coders)
carmenintech
77
5.3k
Code Reviewing Like a Champion
maltzj
528
40k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
270
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
220
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