Slide 1

Slide 1 text

複雑なv-ifに負けないために 1 @Philomagi 2019/09/[email protected] #1 #yumemi_vue

Slide 2

Slide 2 text

発表者 @Philomagi ● 主にフロントエンド主体のWEB系エンジニア ● ScalaとTypescriptとRubyが好き ○ Rubyは最近、公私共に若干疎遠 ● PHPは中々縁が切れない悪友 ○ 最近は、「然程悪いやつでもないな」と思い始めてる 2

Slide 3

Slide 3 text

今回のお題 3

Slide 4

Slide 4 text

v-if 4

Slide 5

Slide 5 text

v-if =「表示条件」 5

Slide 6

Slide 6 text

6
hoge
fuga

Slide 7

Slide 7 text

7
hoge
fuga

Slide 8

Slide 8 text

v-ifを使うことで、 条件に応じて表示を変えられる 8

Slide 9

Slide 9 text

簡単!便利! 9

Slide 10

Slide 10 text

10
hoge
fuga

Slide 11

Slide 11 text

hoge
fuga
11 1. hoge/fuga の他に、piyoという表示もしたい 2. fugaを表示する条件を追加してほしい 3. hogeでもfugaでも無い場合に、 piyoを表示したい

Slide 12

Slide 12 text

12
hoge
fuga
piyo

Slide 13

Slide 13 text

13
hoge
fuga
piyo

Slide 14

Slide 14 text

条件の追加も簡単! 14

Slide 15

Slide 15 text

おしまい 15

Slide 16

Slide 16 text

おしまい 16

Slide 17

Slide 17 text

ご清聴ありがとうございました 17 しばらく後・・・

Slide 18

Slide 18 text

18
hoge
fuga
piyo
xxx
yyy
zzz

Slide 19

Slide 19 text

19 export default { data() { return { shouldShowHoge: /**/, shouldShowFuga: /**/, shouldShowPiyo: /**/, shouldShowXXX: /**/, shouldShowYYY: /**/, shouldShowZZZ: /**/, /* 以下略 */ } }, }

Slide 20

Slide 20 text

20 export default { data() { return { shouldShowHoge: /**/, shouldShowFuga: /**/, shouldShowPiyo: /**/, shouldShowXXX: /**/, shouldShowYYY: /**/, shouldShowZZZ: /**/, /* 以下略 */ } }, } 実際のプロジェクトでは ● computedによる計算が必要だったり ● 処理の中で状態が書き換えられたり 「条件」と「表示」の関係が さらに複雑になってくる

Slide 21

Slide 21 text

出てくる問題 表示の条件が複雑になると 21

Slide 22

Slide 22 text

表示の条件が複雑になると ● htmlもjsも肥大化する 出てくる問題 22

Slide 23

Slide 23 text

出てくる問題 表示の条件が複雑になると ● htmlもjsも肥大化する ○ テストが大変 23

Slide 24

Slide 24 text

出てくる問題 表示の条件が複雑になると ● htmlもjsも肥大化する ○ テストが大変 ○ 影響範囲を把握しづらく、修正しにくい 24

Slide 25

Slide 25 text

どうにか解決したい 25

Slide 26

Slide 26 text

問題を整理する 何故html/jsが肥大化するのか? 26

Slide 27

Slide 27 text

問題を整理する 何故html/jsが肥大化するのか? ● 条件分岐がたくさん有るから ● 条件毎に表示すべき内容が違うから 27

Slide 28

Slide 28 text

問題を整理する 何故html/jsが肥大化するのか? ● 条件分岐がたくさん有るから ● 条件毎に表示すべき内容が違うから 「条件」と「表示」を、 一つにまとめてしまってはどうだろう? 28

Slide 29

Slide 29 text

「条件」が決まれば「表示」も一意に定まる 「条件」と「表示」を一つにする 29

Slide 30

Slide 30 text

「条件」が決まれば「表示」も一意に定まる なら、「条件」と「表示」は 常にセットにして扱った方が便利なのでは? 「条件」と「表示」を一つにする 30

Slide 31

Slide 31 text

「条件」が決まれば「表示」も一意に定まる なら、「条件」と「表示」は 常にセットにして扱った方が便利なのでは? 「条件」と「表示」の対応関係を 1つのオブジェクトで表現してみる 「条件」と「表示」を一つにする 31

Slide 32

Slide 32 text

具体的にコードでは? 32

Slide 33

Slide 33 text

33 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean }

Slide 34

Slide 34 text

34 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean } 「表示」を表すプロパティ定義

Slide 35

Slide 35 text

35 1. 「条件-表示の対応」を表すIFを定義する import { VueConstructor } from 'vue' export interface ShowImageSpec { readonly shown: VueConstructor isSatisfiedBy (param: ShowImageSpecParam): boolean } 「条件」を表すメソッド定義

Slide 36

Slide 36 text

36 2. コンポーネントを作る Vue logo

Slide 37

Slide 37 text

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' } }

Slide 38

Slide 38 text

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' } } 「表示」の内容

Slide 39

Slide 39 text

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' } } 「表示」の内容 「表示」されるべき条件

Slide 40

Slide 40 text

40 4. オブジェクトから「表示」を得る get frameworkView (): VueConstructor { const appliedSpec: ShowImageSpec = applyWithDefault( new ShowKoujichuSpec(), [ new ShowVueSpec(), new ShowHogeSpec() ] ) return appliedSpec.shown } 「表示」を取得

Slide 41

Slide 41 text

41 5. 得た「表示」を適用する

好きなjsのフレームワークは?

Slide 42

Slide 42 text

42 5. 得た「表示」を適用する

好きなjsのフレームワークは?

Slide 43

Slide 43 text

43 5. 得た「表示」を適用する

好きなjsのフレームワークは?

Slide 44

Slide 44 text

44 5. 得た「表示」を適用する

好きなjsのフレームワークは?

is属性にVueConstructorを渡すと、 そのVueコンポーネントをレンダリングしてくれる!

Slide 45

Slide 45 text

45 https://jp.vuejs.org/v2/guide/components.html

Slide 46

Slide 46 text

46 https://jp.vuejs.org/v2/guide/components.html

Slide 47

Slide 47 text

サンプルアプリ (スライドのdescriptionに記載) 47

Slide 48

Slide 48 text

「条件」に対する考え方 48

Slide 49

Slide 49 text

コンポーネントだけで頑張らない 49 ● Vue.jsのSingle File Componentは便利だけど、 その中で全て完結させる必要は無い ● 「表示」について複雑な条件やルールが有るなら、 それも立派な「ロジック」と考えた方が良い ● OOPのテクニックを使えば、コンポーネントも より柔軟かつシンプルにできる

Slide 50

Slide 50 text

フロントにも「ロジック」は有る 50 ● 「表示」はコンポーネントに、 「ロジック」は専門のモジュールに任せる ● 責務・関心を適切に分割しよう

Slide 51

Slide 51 text

まとめ ● 複雑な表示条件はコンポーネントだけで頑張ら ず、「ロジック」として独立させる ● OOPのテクニックを使うことで より柔軟なコンポーネントにできる ● 責務と関心を適切に分離する 51

Slide 52

Slide 52 text

ご清聴ありがとうございました 52