Railsに組み込んだvuetifyがページ遷移をすると読み込まれなくなる現象を解消した

# はじめに
 RailsにいよいよVuetifyを組み込み始めたが、ページ遷移をするとvuetifyのボタンが消えてしまう。ページ更新をするとボタンが表示される。そのような不具合に見舞われた。いったいなにが原因なのか。一週間ほど悩んだのちにようやくわかった。
　turbolinkの問題だった。ちょっとずつ書いていく。

# hello_vue.jsをのぞく
　vue導入時に`app/javascript/packs/hello_vue.js`が作成された。さきの記事ではこいつを編集して、いいようにしていたが、まだここには続きがあった。

```javascript:app/javascript/packs/hello_vue.js
// If the project is using turbolinks, install 'vue-turbolinks':
//
// yarn add vue-turbolinks
//
// Then uncomment the code block below:
```

そういうわけで、

```terminal
$ yarn add vue-turbolinks
```
を実行したのち、`hello_vue.js`を以下のように変更した。

```javascript:app/javascript/packs/hello_vue.js
import TurbolinksAdapter from 'vue-turbolinks' //turbolinkをつかっていたので追加
import Vue from 'vue'
import Vuetify from "vuetify"; // vuetify導入のため追加
import "vuetify/dist/vuetify.min.css"; // vuetify導入のため追加
import App from '../app.vue'

Vue.use(Vuetify); // vuetify導入のため追加
const vuetify = new Vuetify(); // vuetify導入のため追加

Vue.use(TurbolinksAdapter)
document.addEventListener('turbolinks:load', () => {
    const app = new Vue({
    vuetify, // vuetify導入のため追加
      el: '#hello',
      data: {
              message: "Can you say hello?"
            },
      components: { App }
    })
  })
```
　
なんとかなった。

# turbolinkとはなにか
　今回私を悩ませたturbolinkだが、Railsのgemfileにはちゃんと記述があった。

```:Gemfile
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
```

　ページ遷移の速度が向上するらしい。もうちょっとread.meを読んでみよう。
https://github.com/turbolinks/turbolinks

>Turbolinks intercepts all clicks on `<a href>` links to the same domain. When you click an eligible link, Turbolinks prevents the browser from following it. Instead, Turbolinks changes the browser’s URL using the History API, requests the new page using XMLHttpRequest, and then renders the HTML response.

　そういうことらしい。turbolinksはaタグのリンクをクリックすると、その遷移をブロックするらしい。そして、その代わりにHistory APIを利用してHTMLレスポンスを返す。History APIを使ってやるほうがはやくなるらしいね。

　しかし、それがなぜvuetifyに悪影響を及ぼしているのかがわからなかった。

　こんなときは答えのほうからみていくと話が早い。解決策としてvueが提示している`vue-turbolinks`を覗こう。


# vue-turbolinksとは

https://github.com/jeffreyguenther/vue-turbolinks

> vue-turbolinks is a package to allow you to easily add Vue.js components to your Turbolinks & Hotwire powered apps.

　簡単に加えられるぜ！ということらしい。（Hotwireってなんだろ。まぁいいか）

　`index.js`をみると思いの外シンプルだった。

https://github.com/jeffreyguenther/vue-turbolinks/blob/master/index.js

```javascript:vue-turbolinks/index.js
//略
const Mixin = {
  beforeMount: function() {
    // If this is the root component, we want to cache the original element contents to replace later
    // We don't care about sub-components, just the root
    if (this === this.$root && this.$el) {
      handleVueDestruction(this);

      // cache original element
      this.$cachedHTML = this.$el.outerHTML;

      // register root hook to restore original element on destroy
      this.$once('hook:destroyed', function() {
        this.$el.outerHTML = this.$cachedHTML
      });
    }
  }
};
//略
```

vueがmountする前にこれらのfunctionを実行していた。キャッシュされたHTMLの内容を、現在のHTMLに置き換えていた。それだけだった。

なんとなくわかった。torbolinksはキャッシュからリンクをひっぱってくるが、本来のvueはそれをしていなかったのだ。だからvue-turbolinkを使って、キャッシュのところにHTMLを入れ込んでいたのだ。


# おわりに

vueはたのしい。vuetifyはたのしい。
これからも、勉強しながら詰まったところを書いていこう。