書いた時のバージョン
Nuxt 2.2.0
Vue 2.6.6
ネストされたルートの表示でnuxt-childを利用した時、オプションとしてkeep-aliveを使うことができる。
<nuxt-child keep-alive></nuxt-child>
ページが以下の構造になっていて、
user/
--| _id/
-----| activity.vue
-----| index.vue
-----| tweet.vue
index.vue
index.vueにnuxt-childがあると、
keep-aliveによってuser/_id以下のコンポーネントがキャッシュされるようになる。
Vueのドキュメントにあるkeep-ailveのデモを見ると、コンポーネントが切り替わっても選択されたデータが生きている様子が確認できる。
Nuxtを利用している場合でも、keep-aliveによってコンポーネントのデータを保持しておいて欲しいと思うわけだが、nuxt-childにkeep-aliveを追加しただけではうまくいかない。
なぜなら、keep-aliveを設定していてもNuxtが毎回data()を実行するためで、コンポーネントが切り替わる度に初期化されてしまうのだ。
ではどうすればdataも保持できるのか?
このissueにある簡単なサンプルを参考にすると次のようになる。
issueのサンプルではdata()で直接APIを叩いていたが、より複雑になることを見越してmethodsにAPIを叩く関数を書いたならcreatedで実行する。
(createdではthis.$elが参照できないので、this.$elを必要とする処理があるならmountedに変更する)
Vue 2.2.0以降、keep-aliveを利用するとactivatedとdeactivatedが発行される。
gistのサンプルではdeactivatedで保持しているdataを全てcacheData変数にコピーして、data()内でcacheDataがある場合は優先して返すように分岐させた。
ルート変更などでコンポーネントが破棄される前にbeforeDestroyが呼ばれるので、そこでcacheDataを消しておく。
これでコンポーネントを切り替ええてもデータが保持されるようになり、都度APIを叩いていた挙動を最初の1回だけに収めることができる。