Reactではよく使うが、Vueでもちゃんと実現できる。
要点
- パターンを文字列で定義できるように考える
- 例: APIの通信ステータス:
pending | resolve | reject - 例: SNSアイコンの出し分け:
twitter | facebook | instagram | github | line
- 例: APIの通信ステータス:
- パターンごとのコンポーネントをつくる
実装
<script setup lang="ts"> import { computed, ref } from 'vue'; import TwitterIcon from './TwitterIcon.vue'; import FacebookIcon from './FacebookIcon.vue'; import InstagramIcon from './InstagramIcon.vue';
type IconType = "twitter" | "facebook" | "instagram";
const icons = { twitter: TwitterIcon, facebook: FacebookIcon, instagram: InstagramIcon; }
const iconType = ref<IconType>("twitter");
const currentIconComponent = computed(() => { return icons[iconType.value] })
// function showTwitterIcon // function showFacebookIcon // function showInstagramIcon</script>
<template> <div class="flex gap-1 m-4"> <button @click="showTwitterIcon">Twitter</button> <button @click="showFacebookIcon">Facebook</button> <button @click="showInstagramIcon">Instagram</button> </div>
<component :is="currentIconComponent" /></template>ポイント
- オブジェクトマッピング: パターン文字列とコンポーネントをマッピング
- 動的コンポーネント:
<component :is="...">で動的に切り替え - 型安全性: TypeScriptでパターンを Union Type で定義
まとめ
v-ifで3パターン以上の分岐が発生したら、ストラテジーパターンを検討しよう。
動的コンポーネントを使えば、テンプレートがすっきりし、新しいパターンの追加も容易になる。
hsb.horse