Vue.js の keep-alive でコンポーネントを維持する

最終更新日
2018.03.05

keep-alive を使うと、コンポーネントが切り替わったときにインスタンスを削除せずに状態を維持できるようになるみたい。

コンポーネントの状態を維持

通常コンポーネントの描画を v-if で切り替えたり、:is="component" で動的に切り替えた場合、コンポーネントは毎回破棄され状態が初期化されます。

次の例ではカウンターを増加させても切り替えのたびに「0」に戻ってしまう!

<div id="app">
  <button @click="current='child1'">child1</button>
  <button @click="current='child2'">child2</button>
  <button @click="current=null" v-show="current">close</button>
  <child-comp v-if="current=='child1'" key="child1"></child-comp>
  <child-comp v-if="current=='child2'" key="child2"></child-comp>
</div>
<script type="text/x-template" id="template-tab">
  <div>
    <h2>{{ $vnode.key }}</h2>
    <p>Count: {{ count }} <button @click="count++">click</button></p>
  </div>
</script>
Vue.component('child-comp', {
  template: '#template-tab',
  data() {
    return {
      count: 0
    }
  }
})
new Vue({
  el: '#app',
  data: {
    current: null
  }
})

コンポーネントを次のように <keep-alive/> タグで囲むと切り替えても状態を維持します。

<keep-alive>
  <child-comp v-if="current=='child1'" key="child1"></child-comp>
  <child-comp v-if="current=='child2'" key="child2"></child-comp>
</keep-alive>

<keep-alive/> に囲まれているコンポーネントは、その親のコンポーネントが破棄されるときに一緒に破棄されます。

特定のコンポーネントだけ維持させる

次のオプションで特定のコンポーネントだけを許可、除外出来ます。

  • include - 指定したコンポーネントのみ維持する
  • exclude - 指定したコンポーネントのみ維持しない

値には正規表現が使えます。その場合は式タイプにする。

<keep-alive :include="/^Hoge/"></keep-alive>

keep-aliveモードで呼ばれているかを確認する

次のライフサイクルフックを使用して状態を確認出来ます。

  • activated - keep-aliveモードでコンポーネントの使用を開始した時
  • deactivated - keep-aliveモードでコンポーネントの使用を終了した時

上のデモを実行するとコンソール画面からどのようにライフサイクルが発生しているか確認出来ます。

ルータービューの状態を維持

<router-view/> もコンポーネントなので同じように維持することが出来ます。

上のデモはルーターを使用して掲示板とフォームでページを分けています。 <keep-alive/> を使うとページを切り替えて掲示板の内容を確認しながらコメントを入力出来ます。

transition との併用

<keep-alive/> を内側に書くようだ。

<transition>
  <keep-alive>
    <router-view/>
  </keep-alive>
</transition>

コンポーネントの状態を維持しながらページを遷移するので、API との不要な通信を減らすこともできそう。