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
Androidアプリのモジュール分割における:x:commonを考える
okuzawats
1
280
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
4
1.1k
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
240
traP の部内 ISUCON とそれを支えるポータル / PISCON Portal
ikura_hamu
0
180
ATDDで素早く安定した デリバリを実現しよう!
tonnsama
1
1.9k
いりゃあせ、PHPカンファレンス名古屋2025 / Welcome to PHP Conference Nagoya 2025
ttskch
1
180
ASP.NET Core の OpenAPIサポート
h455h1
0
120
DevFest - Serverless 101 with Google Cloud Functions
tunmise
0
140
BEエンジニアがFEの業務をできるようになるまでにやったこと
yoshida_ryushin
0
200
return文におけるstd::moveについて
onihusube
1
1.4k
QA環境で誰でも自由自在に現在時刻を操って検証できるようにした話
kalibora
1
140
歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス
i10416
0
300
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
137
6.7k
Designing Experiences People Love
moore
139
23k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Thoughts on Productivity
jonyablonski
68
4.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Music & Morning Musume
bryan
46
6.3k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Embracing the Ebb and Flow
colly
84
4.5k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
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