🐸

Vue の <component> と <keep-alive>:動的コンポーネントの切り替えと状態の保持

に公開

はじめに

Vue の <component> タグは、動的にコンポーネントを切り替える便利な方法です。
例えば「タブ切り替え」や「ページの差し替え」などで使われます。
さらに <keep-alive> と組み合わせることで、切り替えたコンポーネントの状態を保持することも可能です。

本記事では、以下の2点を中心に解説します:

  • <component :is="..."> の使い方
  • <keep-alive> の挙動と使い所

<component> の基本

Vue の <component> タグを使うと、変数に応じて表示するコンポーネントを切り替えられます。

例:ボタンをクリックして表示するコンポーネントを切り替える

<script setup lang="ts">
import { ref, computed } from "vue";
import Foo from "./components/Foo.vue";
import Bar from "./components/Bar.vue";

// コンポーネントのマップを定義
type ComponentKey = "Foo" | "Bar";

// 現在表示中のコンポーネントキーを定義
const viewComponent = ref<ComponentKey>("Foo");

const buttonClick = () => {
  viewComponent.value = viewComponent.value === "Foo" ? "Bar" : "Foo";
};

// componentを切り替える
const currentComponent = computed(() => {
  if (viewComponent.value === "Foo") return Foo;
  return Bar;
});
</script>

<template>
  <button @click="buttonClick">コンポーネントを切り替え</button>
  <keep-alive>
    <component :is="currentComponent" />
  </keep-alive>
</template>

これにより viewComponent.value を切り替えるだけで、表示されるコンポーネントが Foo.vueBar.vue の間で動的に変化します。

Foo.vue

<script setup lang="ts">
import { ref } from "vue";
const inputValue = ref("");
</script>

<template>
  <h1>Foo</h1>
  <input type="text" v-model="inputValue" />
  <p>{{ inputValue }}</p>
</template>

Bar.vue

<script setup lang="ts">
import { ref } from "vue";
const inputValue = ref("");
</script>

<template>
  <h1>Bar</h1>
  <input type="text" v-model="inputValue" />
  <p>{{ inputValue }}</p>
</template>


<keep-alive> を指定していることで、コンポーネントを切り替えても input の入力値が保持されます。これは、Vue がそれぞれのコンポーネントを一度だけマウントし、非表示の際もインスタンスをキャッシュしているためです。

まとめ

  • <component :is="..."> を使うと、動的にコンポーネントを切り替えられる
  • <keep-alive> を組み合わせることで、切り替えたコンポーネントの状態を保持できる
  • タブ切り替えやページ表示の最適化に活用できる

詳細は公式ドキュメントも参考にしてください:
https://jp.vuejs.org/api/built-in-components.html#keep-alive

Discussion